1 /*! This library describes the API surface of WebGPU that is agnostic of the backend.
2 * This API is used for targeting both Web and Native.
6 // We don't use syntax sugar where it's not necessary.
7 clippy::match_like_matches_macro,
11 #[cfg(feature = "serde")]
12 use serde::{Deserialize, Serialize};
13 use std::{num::NonZeroU32, ops::Range};
15 /// Integral type used for buffer offsets.
16 pub type BufferAddress = u64;
17 /// Integral type used for buffer slice sizes.
18 pub type BufferSize = std::num::NonZeroU64;
19 /// Integral type used for binding locations in shaders.
20 pub type ShaderLocation = u32;
21 /// Integral type used for dynamic bind group offsets.
22 pub type DynamicOffset = u32;
24 /// Buffer-Texture copies must have [`bytes_per_row`] aligned to this number.
26 /// This doesn't apply to [`Queue::write_texture`][Qwt].
28 /// [`bytes_per_row`]: ImageDataLayout::bytes_per_row
29 /// [Qwt]: ../wgpu/struct.Queue.html#method.write_texture
30 pub const COPY_BYTES_PER_ROW_ALIGNMENT: u32 = 256;
31 /// An offset into the query resolve buffer has to be aligned to this.
32 pub const QUERY_RESOLVE_BUFFER_ALIGNMENT: BufferAddress = 256;
33 /// Buffer to buffer copy as well as buffer clear offsets and sizes must be aligned to this number.
34 pub const COPY_BUFFER_ALIGNMENT: BufferAddress = 4;
35 /// Size to align mappings.
36 pub const MAP_ALIGNMENT: BufferAddress = 8;
37 /// Vertex buffer strides have to be aligned to this number.
38 pub const VERTEX_STRIDE_ALIGNMENT: BufferAddress = 4;
39 /// Alignment all push constants need
40 pub const PUSH_CONSTANT_ALIGNMENT: u32 = 4;
41 /// Maximum queries in a query set
42 pub const QUERY_SET_MAX_QUERIES: u32 = 8192;
43 /// Size of a single piece of query data.
44 pub const QUERY_SIZE: u32 = 8;
46 /// Backends supported by wgpu.
48 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
49 #[cfg_attr(feature = "trace", derive(Serialize))]
50 #[cfg_attr(feature = "replay", derive(Deserialize))]
52 /// Dummy backend, used for testing.
56 /// Metal API (Apple platforms)
58 /// Direct3D-12 (Windows)
60 /// Direct3D-11 (Windows)
62 /// OpenGL ES-3 (Linux, Android)
64 /// WebGPU in the browser
68 /// Power Preference when choosing a physical adapter.
70 /// Corresponds to [WebGPU `GPUPowerPreference`](
71 /// https://gpuweb.github.io/gpuweb/#enumdef-gpupowerpreference).
73 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
74 #[cfg_attr(feature = "trace", derive(Serialize))]
75 #[cfg_attr(feature = "replay", derive(Deserialize))]
76 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
77 pub enum PowerPreference {
78 /// Adapter that uses the least possible power. This is often an integrated GPU.
80 /// Adapter that has the highest performance. This is often a discrete GPU.
84 impl Default for PowerPreference {
85 fn default() -> Self {
91 /// Represents the backends that wgpu will use.
93 pub struct Backends: u32 {
94 /// Supported on Windows, Linux/Android, and macOS/iOS via Vulkan Portability (with the Vulkan feature enabled)
95 const VULKAN = 1 << Backend::Vulkan as u32;
96 /// Currently unsupported
97 const GL = 1 << Backend::Gl as u32;
98 /// Supported on macOS/iOS
99 const METAL = 1 << Backend::Metal as u32;
100 /// Supported on Windows 10
101 const DX12 = 1 << Backend::Dx12 as u32;
102 /// Supported on Windows 7+
103 const DX11 = 1 << Backend::Dx11 as u32;
104 /// Supported when targeting the web through webassembly
105 const BROWSER_WEBGPU = 1 << Backend::BrowserWebGpu as u32;
106 /// All the apis that wgpu offers first tier of support for.
108 /// Vulkan + Metal + DX12 + Browser WebGPU
109 const PRIMARY = Self::VULKAN.bits
112 | Self::BROWSER_WEBGPU.bits;
113 /// All the apis that wgpu offers second tier of support for. These may
114 /// be unsupported/still experimental.
117 const SECONDARY = Self::GL.bits | Self::DX11.bits;
121 #[cfg(feature = "bitflags_serde_shim")]
122 bitflags_serde_shim::impl_serde_for_bitflags!(Backends);
124 impl From<Backend> for Backends {
125 fn from(backend: Backend) -> Self {
126 Self::from_bits(1 << backend as u32).unwrap()
130 /// Options for requesting adapter.
132 /// Corresponds to [WebGPU `GPURequestAdapterOptions`](
133 /// https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions).
135 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
136 #[cfg_attr(feature = "trace", derive(Serialize))]
137 #[cfg_attr(feature = "replay", derive(Deserialize))]
138 pub struct RequestAdapterOptions<S> {
139 /// Power preference for the adapter.
140 pub power_preference: PowerPreference,
141 /// Indicates that only a fallback adapter can be returned. This is generally a "software"
142 /// implementation on the system.
143 pub force_fallback_adapter: bool,
144 /// Surface that is required to be presentable with the requested adapter. This does not
145 /// create the surface, only guarantees that the adapter can present to said surface.
146 pub compatible_surface: Option<S>,
149 impl<S> Default for RequestAdapterOptions<S> {
150 fn default() -> Self {
152 power_preference: PowerPreference::default(),
153 force_fallback_adapter: false,
154 compatible_surface: None,
159 //TODO: make robust resource access configurable
161 bitflags::bitflags! {
162 /// Features that are not guaranteed to be supported.
164 /// These are either part of the webgpu standard, or are extension features supported by
165 /// wgpu when targeting native.
167 /// If you want to use a feature, you need to first verify that the adapter supports
168 /// the feature. If the adapter does not support the feature, requesting a device with it enabled
171 /// Corresponds to [WebGPU `GPUFeatureName`](
172 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufeaturename).
175 pub struct Features: u64 {
177 // ---- Start numbering at 1 << 0 ----
182 /// By default, polygon depth is clipped to 0-1 range before/during rasterization.
183 /// Anything outside of that range is rejected, and respective fragments are not touched.
185 /// With this extension, we can disabling clipping. That allows
186 /// shadow map occluders to be rendered into a tighter depth range.
188 /// Supported platforms:
190 /// - some mobile chips
192 /// This is a web and native feature.
193 const DEPTH_CLIP_CONTROL = 1 << 0;
194 /// Allows for explicit creation of textures of format [`TextureFormat::Depth24UnormStencil8`]
196 /// Supported platforms:
199 /// - Metal (Macs with amd GPUs)
201 /// This is a web and native feature.
202 const DEPTH24UNORM_STENCIL8 = 1 << 1;
203 /// Allows for explicit creation of textures of format [`TextureFormat::Depth32FloatStencil8`]
205 /// Supported platforms:
206 /// - Vulkan (mostly)
210 /// This is a web and native feature.
211 const DEPTH32FLOAT_STENCIL8 = 1 << 2;
212 /// Enables BCn family of compressed textures. All BCn textures use 4x4 pixel blocks
213 /// with 8 or 16 bytes per block.
215 /// Compressed textures sacrifice some quality in exchange for significantly reduced
218 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for BCn formats.
219 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
221 /// Supported Platforms:
224 /// This is a web and native feature.
225 const TEXTURE_COMPRESSION_BC = 1 << 3;
226 /// Enables ETC family of compressed textures. All ETC textures use 4x4 pixel blocks.
227 /// ETC2 RGB and RGBA1 are 8 bytes per block. RTC2 RGBA8 and EAC are 16 bytes per block.
229 /// Compressed textures sacrifice some quality in exchange for significantly reduced
232 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ETC2 formats.
233 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
235 /// Supported Platforms:
239 /// This is a web and native feature.
240 const TEXTURE_COMPRESSION_ETC2 = 1 << 4;
241 /// Enables ASTC family of compressed textures. ASTC textures use pixel blocks varying from 4x4 to 12x12.
242 /// Blocks are always 16 bytes.
244 /// Compressed textures sacrifice some quality in exchange for significantly reduced
247 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats.
248 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
250 /// Supported Platforms:
254 /// This is a web and native feature.
255 const TEXTURE_COMPRESSION_ASTC_LDR = 1 << 5;
256 /// Allows non-zero value for the "first instance" in indirect draw calls.
258 /// Supported Platforms:
259 /// - Vulkan (mostly)
263 /// This is a web and native feature.
264 const INDIRECT_FIRST_INSTANCE = 1 << 6;
265 /// Enables use of Timestamp Queries. These queries tell the current gpu timestamp when
266 /// all work before the query is finished. Call [`CommandEncoder::write_timestamp`],
267 /// [`RenderPassEncoder::write_timestamp`], or [`ComputePassEncoder::write_timestamp`] to
268 /// write out a timestamp.
270 /// They must be resolved using [`CommandEncoder::resolve_query_sets`] into a buffer,
271 /// then the result must be multiplied by the timestamp period [`Queue::get_timestamp_period`]
272 /// to get the timestamp in nanoseconds. Multiple timestamps can then be diffed to get the
273 /// time for operations between them to finish.
275 /// Due to wgpu-hal limitations, this is only supported on vulkan for now.
277 /// Supported Platforms:
281 /// This is a web and native feature.
282 const TIMESTAMP_QUERY = 1 << 7;
283 /// Enables use of Pipeline Statistics Queries. These queries tell the count of various operations
284 /// performed between the start and stop call. Call [`RenderPassEncoder::begin_pipeline_statistics_query`] to start
285 /// a query, then call [`RenderPassEncoder::end_pipeline_statistics_query`] to stop one.
287 /// They must be resolved using [`CommandEncoder::resolve_query_sets`] into a buffer.
288 /// The rules on how these resolve into buffers are detailed in the documentation for [`PipelineStatisticsTypes`].
290 /// Due to wgpu-hal limitations, this is only supported on vulkan for now.
292 /// Supported Platforms:
296 /// This is a web and native feature.
297 const PIPELINE_STATISTICS_QUERY = 1 << 8;
298 /// Allows shaders to acquire the FP16 ability
300 /// Note: this is not supported in naga yet,only through spir-v passthrough right now.
302 /// Supported Platforms:
306 /// This is a web and native feature.
307 const SHADER_FLOAT16 = 1 << 9;
310 // ---- Restart Numbering for Native Features ---
315 /// Webgpu only allows the MAP_READ and MAP_WRITE buffer usage to be matched with
316 /// COPY_DST and COPY_SRC respectively. This removes this requirement.
318 /// This is only beneficial on systems that share memory between CPU and GPU. If enabled
319 /// on a system that doesn't, this can severely hinder performance. Only use if you understand
320 /// the consequences.
322 /// Supported platforms:
325 /// This is a native only feature.
326 const MAPPABLE_PRIMARY_BUFFERS = 1 << 16;
327 /// Allows the user to create uniform arrays of textures in shaders:
330 /// `var textures: binding_array<texture_2d<f32>, 10>` (WGSL)\
331 /// `uniform texture2D textures[10]` (GLSL)
333 /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user
334 /// may also create uniform arrays of storage textures.
337 /// `var textures: array<texture_storage_2d<f32, write>, 10>` (WGSL)\
338 /// `uniform image2D textures[10]` (GLSL)
340 /// This capability allows them to exist and to be indexed by dynamically uniform
343 /// Supported platforms:
345 /// - Metal (with MSL 2.0+ on macOS 10.13+)
348 /// This is a native only feature.
349 const TEXTURE_BINDING_ARRAY = 1 << 17;
350 /// Allows the user to create arrays of buffers in shaders:
353 /// `var<uniform> buffer_array: array<MyBuffer, 10>` (WGSL)\
354 /// `uniform myBuffer { ... } buffer_array[10]` (GLSL)
356 /// This capability allows them to exist and to be indexed by dynamically uniform
359 /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user
360 /// may also create arrays of storage buffers.
363 /// `var<storage> buffer_array: array<MyBuffer, 10>` (WGSL)\
364 /// `buffer myBuffer { ... } buffer_array[10]` (GLSL)
366 /// Supported platforms:
370 /// This is a native only feature.
371 const BUFFER_BINDING_ARRAY = 1 << 18;
372 /// Allows the user to create uniform arrays of storage buffers or textures in shaders,
373 /// if resp. [`Features::BUFFER_BINDING_ARRAY`] or [`Features::TEXTURE_BINDING_ARRAY`]
376 /// This capability allows them to exist and to be indexed by dynamically uniform
379 /// Supported platforms:
380 /// - Metal (with MSL 2.2+ on macOS 10.13+)
383 /// This is a native only feature.
384 const STORAGE_RESOURCE_BINDING_ARRAY = 1 << 19;
385 /// Allows shaders to index sampled texture and storage buffer resource arrays with dynamically non-uniform values:
387 /// ex. `texture_array[vertex_data]`
389 /// In order to use this capability, the corresponding GLSL extension must be enabled like so:
391 /// `#extension GL_EXT_nonuniform_qualifier : require`
393 /// and then used either as `nonuniformEXT` qualifier in variable declaration:
395 /// ex. `layout(location = 0) nonuniformEXT flat in int vertex_data;`
397 /// or as `nonuniformEXT` constructor:
399 /// ex. `texture_array[nonuniformEXT(vertex_data)]`
401 /// WGSL and HLSL do not need any extension.
403 /// Supported platforms:
405 /// - Metal (with MSL 2.0+ on macOS 10.13+)
406 /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderSampledImageArrayNonUniformIndexing & shaderStorageBufferArrayNonUniformIndexing feature)
408 /// This is a native only feature.
409 const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 20;
410 /// Allows shaders to index uniform buffer and storage texture resource arrays with dynamically non-uniform values:
412 /// ex. `texture_array[vertex_data]`
414 /// In order to use this capability, the corresponding GLSL extension must be enabled like so:
416 /// `#extension GL_EXT_nonuniform_qualifier : require`
418 /// and then used either as `nonuniformEXT` qualifier in variable declaration:
420 /// ex. `layout(location = 0) nonuniformEXT flat in int vertex_data;`
422 /// or as `nonuniformEXT` constructor:
424 /// ex. `texture_array[nonuniformEXT(vertex_data)]`
426 /// WGSL and HLSL do not need any extension.
428 /// Supported platforms:
430 /// - Metal (with MSL 2.0+ on macOS 10.13+)
431 /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderUniformBufferArrayNonUniformIndexing & shaderStorageTextureArrayNonUniformIndexing feature)
433 /// This is a native only feature.
434 const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 21;
435 /// Allows the user to create bind groups continaing arrays with less bindings than the BindGroupLayout.
437 /// This is a native only feature.
438 const PARTIALLY_BOUND_BINDING_ARRAY = 1 << 22;
439 /// Allows the user to call [`RenderPass::multi_draw_indirect`] and [`RenderPass::multi_draw_indexed_indirect`].
441 /// Allows multiple indirect calls to be dispatched from a single buffer.
443 /// Supported platforms:
446 /// - Metal (Emulated on top of `draw_indirect` and `draw_indexed_indirect`)
448 /// This is a native only feature.
449 const MULTI_DRAW_INDIRECT = 1 << 23;
450 /// Allows the user to call [`RenderPass::multi_draw_indirect_count`] and [`RenderPass::multi_draw_indexed_indirect_count`].
452 /// This allows the use of a buffer containing the actual number of draw calls.
454 /// Supported platforms:
456 /// - Vulkan 1.2+ (or VK_KHR_draw_indirect_count)
458 /// This is a native only feature.
459 const MULTI_DRAW_INDIRECT_COUNT = 1 << 24;
460 /// Allows the use of push constants: small, fast bits of memory that can be updated
461 /// inside a [`RenderPass`].
463 /// Allows the user to call [`RenderPass::set_push_constants`], provide a non-empty array
464 /// to [`PipelineLayoutDescriptor`], and provide a non-zero limit to [`Limits::max_push_constant_size`].
466 /// A block of push constants can be declared with `layout(push_constant) uniform Name {..}` in shaders.
468 /// Supported platforms:
472 /// - DX11 (emulated with uniforms)
473 /// - OpenGL (emulated with uniforms)
475 /// This is a native only feature.
476 const PUSH_CONSTANTS = 1 << 25;
477 /// Allows the use of [`AddressMode::ClampToBorder`] with a border color
478 /// other than [`SamplerBorderColor::Zero`].
480 /// Supported platforms:
483 /// - Metal (macOS 10.12+ only)
487 /// This is a web and native feature.
488 const ADDRESS_MODE_CLAMP_TO_BORDER = 1 << 26;
489 /// Allows the user to set [`PolygonMode::Line`] in [`PrimitiveState::polygon_mode`]
491 /// This allows drawing polygons/triangles as lines (wireframe) instead of filled
493 /// Supported platforms:
498 /// This is a native only feature.
499 const POLYGON_MODE_LINE = 1 << 27;
500 /// Allows the user to set [`PolygonMode::Point`] in [`PrimitiveState::polygon_mode`]
502 /// This allows only drawing the vertices of polygons/triangles instead of filled
504 /// Supported platforms:
508 /// This is a native only feature.
509 const POLYGON_MODE_POINT = 1 << 28;
510 /// Enables device specific texture format features.
512 /// See `TextureFormatFeatures` for a listing of the features in question.
514 /// By default only texture format properties as defined by the WebGPU specification are allowed.
515 /// Enabling this feature flag extends the features of each format to the ones supported by the current device.
516 /// Note that without this flag, read/write storage access is not allowed at all.
518 /// This extension does not enable additional formats.
520 /// This is a native-only feature.
521 const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 1 << 29;
522 /// Enables 64-bit floating point types in SPIR-V shaders.
524 /// Note: even when supported by GPU hardware, 64-bit floating point operations are
525 /// frequently between 16 and 64 _times_ slower than equivalent operations on 32-bit floats.
527 /// Supported Platforms:
530 /// This is a native-only feature.
531 const SHADER_FLOAT64 = 1 << 30;
532 /// Enables using 64-bit types for vertex attributes.
534 /// Requires SHADER_FLOAT64.
536 /// Supported Platforms: N/A
538 /// This is a native-only feature.
539 const VERTEX_ATTRIBUTE_64BIT = 1 << 31;
540 /// Allows the user to set a overestimation-conservative-rasterization in [`PrimitiveState::conservative`]
542 /// Processing of degenerate triangles/lines is hardware specific.
543 /// Only triangles are supported.
545 /// Supported platforms:
548 /// This is a native only feature.
549 const CONSERVATIVE_RASTERIZATION = 1 << 32;
550 /// Enables bindings of writable storage buffers and textures visible to vertex shaders.
552 /// Note: some (tiled-based) platforms do not support vertex shaders with any side-effects.
554 /// Supported Platforms:
557 /// This is a native-only feature.
558 const VERTEX_WRITABLE_STORAGE = 1 << 33;
559 /// Enables clear to zero for textures.
561 /// Supported platforms:
564 /// This is a native only feature.
565 const CLEAR_TEXTURE = 1 << 34;
566 /// Enables creating shader modules from SPIR-V binary data (unsafe).
568 /// SPIR-V data is not parsed or interpreted in any way; you can use
569 /// [`wgpu::make_spirv_raw!`] to check for alignment and magic number when converting from
572 /// Supported platforms:
573 /// - Vulkan, in case shader's requested capabilities and extensions agree with
574 /// Vulkan implementation.
576 /// This is a native only feature.
577 const SPIRV_SHADER_PASSTHROUGH = 1 << 35;
578 /// Enables `builtin(primitive_index)` in fragment shaders.
580 /// Note: enables geometry processing for pipelines using the builtin.
581 /// This may come with a significant performance impact on some hardware.
582 /// Other pipelines are not affected.
584 /// Supported platforms:
587 /// This is a native only feature.
588 const SHADER_PRIMITIVE_INDEX = 1 << 36;
589 /// Enables multiview render passes and `builtin(view_index)` in vertex shaders.
591 /// Supported platforms:
594 /// This is a native only feature.
595 const MULTIVIEW = 1 << 37;
596 /// Enables normalized `16-bit` texture formats.
598 /// Supported platforms:
603 /// This is a native only feature.
604 const TEXTURE_FORMAT_16BIT_NORM = 1 << 38;
605 /// Allows the use of [`AddressMode::ClampToBorder`] with a border color
606 /// of [`SamplerBorderColor::Zero`].
608 /// Supported platforms:
615 /// This is a native only feature.
616 const ADDRESS_MODE_CLAMP_TO_ZERO = 1 << 39;
617 /// Enables ASTC HDR family of compressed textures.
619 /// Compressed textures sacrifice some quality in exchange for significantly reduced
622 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for BCn formats.
623 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
625 /// Supported Platforms:
629 /// This is a native-only feature.
630 const TEXTURE_COMPRESSION_ASTC_HDR = 1 << 40;
631 /// Allows for timestamp queries inside renderpasses. Metal does not allow this
634 /// Implies [`Features::TIMESTAMP_QUERIES`] is supported.
636 /// Supported platforms:
639 /// - Metal (Intel and AMD GPUs)
640 const WRITE_TIMESTAMP_INSIDE_PASSES = 1 << 41;
644 #[cfg(feature = "bitflags_serde_shim")]
645 bitflags_serde_shim::impl_serde_for_bitflags!(Features);
648 /// Mask of all features which are part of the upstream WebGPU standard.
649 pub const fn all_webgpu_mask() -> Self {
650 Self::from_bits_truncate(0x0000_0000_0000_FFFF)
653 /// Mask of all features that are only available when targeting native (not web).
654 pub const fn all_native_mask() -> Self {
655 Self::from_bits_truncate(0xFFFF_FFFF_FFFF_0000)
659 /// Represents the sets of limits an adapter/device supports.
661 /// We provide three different defaults.
662 /// - [`Limits::downlevel_defaults()`]. This is a set of limits that is guaranteed to work on almost
663 /// all backends, including "downlevel" backends such as OpenGL and D3D11, other than WebGL. For
664 /// most applications we recommend using these limits, assuming they are high enough for your
665 /// application, and you do not intent to support WebGL.
666 /// - [`Limits::downlevel_webgl2_defaults()`] This is a set of limits that is lower even than the
667 /// [`downlevel_defaults()`], configured to be low enough to support running in the browser using
669 /// - [`Limits::default()`]. This is the set of limits that is guarenteed to work on all modern
670 /// backends and is guarenteed to be supported by WebGPU. Applications needing more modern
671 /// features can use this as a reasonable set of limits if they are targetting only desktop and
672 /// modern mobile devices.
674 /// We recommend starting with the most restrictive limits you can and manually increasing the
675 /// limits you need boosted. This will let you stay running on all hardware that supports the limits
678 /// Limits "better" than the default must be supported by the adapter and requested when requesting
679 /// a device. If limits "better" than the adapter supports are requested, requesting a device will
680 /// panic. Once a device is requested, you may only use resources up to the limits requested _even_
681 /// if the adapter supports "better" limits.
683 /// Requesting limits that are "better" than you need may cause performance to decrease because the
684 /// implementation needs to support more than is needed. You should ideally only request exactly
687 /// Corresponds to [WebGPU `GPUSupportedLimits`](
688 /// https://gpuweb.github.io/gpuweb/#gpusupportedlimits).
690 /// [`downlevel_defaults()`]: Limits::downlevel_defaults
692 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
693 #[cfg_attr(feature = "trace", derive(Serialize))]
694 #[cfg_attr(feature = "replay", derive(Deserialize))]
695 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
697 /// Maximum allowed value for the `size.width` of a texture created with `TextureDimension::D1`.
698 /// Defaults to 8192. Higher is "better".
699 pub max_texture_dimension_1d: u32,
700 /// Maximum allowed value for the `size.width` and `size.height` of a texture created with `TextureDimension::D2`.
701 /// Defaults to 8192. Higher is "better".
702 pub max_texture_dimension_2d: u32,
703 /// Maximum allowed value for the `size.width`, `size.height`, and `size.depth_or_array_layers`
704 /// of a texture created with `TextureDimension::D3`.
705 /// Defaults to 2048. Higher is "better".
706 pub max_texture_dimension_3d: u32,
707 /// Maximum allowed value for the `size.depth_or_array_layers` of a texture created with
708 /// `TextureDimension::D1` or `TextureDimension::D2`.
709 /// Defaults to 256. Higher is "better".
710 pub max_texture_array_layers: u32,
711 /// Amount of bind groups that can be attached to a pipeline at the same time. Defaults to 4. Higher is "better".
712 pub max_bind_groups: u32,
713 /// Amount of uniform buffer bindings that can be dynamic in a single pipeline. Defaults to 8. Higher is "better".
714 pub max_dynamic_uniform_buffers_per_pipeline_layout: u32,
715 /// Amount of storage buffer bindings that can be dynamic in a single pipeline. Defaults to 4. Higher is "better".
716 pub max_dynamic_storage_buffers_per_pipeline_layout: u32,
717 /// Amount of sampled textures visible in a single shader stage. Defaults to 16. Higher is "better".
718 pub max_sampled_textures_per_shader_stage: u32,
719 /// Amount of samplers visible in a single shader stage. Defaults to 16. Higher is "better".
720 pub max_samplers_per_shader_stage: u32,
721 /// Amount of storage buffers visible in a single shader stage. Defaults to 8. Higher is "better".
722 pub max_storage_buffers_per_shader_stage: u32,
723 /// Amount of storage textures visible in a single shader stage. Defaults to 8. Higher is "better".
724 pub max_storage_textures_per_shader_stage: u32,
725 /// Amount of uniform buffers visible in a single shader stage. Defaults to 12. Higher is "better".
726 pub max_uniform_buffers_per_shader_stage: u32,
727 /// Maximum size in bytes of a binding to a uniform buffer. Defaults to 64 KB. Higher is "better".
728 pub max_uniform_buffer_binding_size: u32,
729 /// Maximum size in bytes of a binding to a storage buffer. Defaults to 128 MB. Higher is "better".
730 pub max_storage_buffer_binding_size: u32,
731 /// Maximum length of `VertexState::buffers` when creating a `RenderPipeline`.
732 /// Defaults to 8. Higher is "better".
733 pub max_vertex_buffers: u32,
734 /// Maximum length of `VertexBufferLayout::attributes`, summed over all `VertexState::buffers`,
735 /// when creating a `RenderPipeline`.
736 /// Defaults to 16. Higher is "better".
737 pub max_vertex_attributes: u32,
738 /// Maximum value for `VertexBufferLayout::array_stride` when creating a `RenderPipeline`.
739 /// Defaults to 2048. Higher is "better".
740 pub max_vertex_buffer_array_stride: u32,
741 /// Amount of storage available for push constants in bytes. Defaults to 0. Higher is "better".
742 /// Requesting more than 0 during device creation requires [`Features::PUSH_CONSTANTS`] to be enabled.
744 /// Expect the size to be:
745 /// - Vulkan: 128-256 bytes
746 /// - DX12: 256 bytes
747 /// - Metal: 4096 bytes
748 /// - DX11 & OpenGL don't natively support push constants, and are emulated with uniforms,
749 /// so this number is less useful but likely 256.
750 pub max_push_constant_size: u32,
751 /// Required `BufferBindingType::Uniform` alignment for `BufferBinding::offset`
752 /// when creating a `BindGroup`, or for `set_bind_group` `dynamicOffsets`.
753 /// Defaults to 256. Lower is "better".
754 pub min_uniform_buffer_offset_alignment: u32,
755 /// Required `BufferBindingType::Storage` alignment for `BufferBinding::offset`
756 /// when creating a `BindGroup`, or for `set_bind_group` `dynamicOffsets`.
757 /// Defaults to 256. Lower is "better".
758 pub min_storage_buffer_offset_alignment: u32,
759 /// Maximum allowed number of components (scalars) of input or output locations for
760 /// inter-stage communication (vertex outputs to fragment inputs). Defaults to 60.
761 pub max_inter_stage_shader_components: u32,
762 /// Maximum number of bytes used for workgroup memory in a compute entry point. Defaults to
764 pub max_compute_workgroup_storage_size: u32,
765 /// Maximum value of the product of the `workgroup_size` dimensions for a compute entry-point.
767 pub max_compute_invocations_per_workgroup: u32,
768 /// The maximum value of the workgroup_size X dimension for a compute stage `ShaderModule` entry-point.
770 pub max_compute_workgroup_size_x: u32,
771 /// The maximum value of the workgroup_size Y dimension for a compute stage `ShaderModule` entry-point.
773 pub max_compute_workgroup_size_y: u32,
774 /// The maximum value of the workgroup_size Z dimension for a compute stage `ShaderModule` entry-point.
776 pub max_compute_workgroup_size_z: u32,
777 /// The maximum value for each dimension of a `ComputePass::dispatch(x, y, z)` operation.
778 /// Defaults to 65535.
779 pub max_compute_workgroups_per_dimension: u32,
780 /// A limit above which buffer allocations are guaranteed to fail.
782 /// Buffer allocations below the maximum buffer size may not succed depending on available memory,
783 /// fragmentation and other factors.
784 pub max_buffer_size: u64,
787 impl Default for Limits {
788 fn default() -> Self {
790 max_texture_dimension_1d: 8192,
791 max_texture_dimension_2d: 8192,
792 max_texture_dimension_3d: 2048,
793 max_texture_array_layers: 256,
795 max_dynamic_uniform_buffers_per_pipeline_layout: 8,
796 max_dynamic_storage_buffers_per_pipeline_layout: 4,
797 max_sampled_textures_per_shader_stage: 16,
798 max_samplers_per_shader_stage: 16,
799 max_storage_buffers_per_shader_stage: 8,
800 max_storage_textures_per_shader_stage: 8,
801 max_uniform_buffers_per_shader_stage: 12,
802 max_uniform_buffer_binding_size: 64 << 10,
803 max_storage_buffer_binding_size: 128 << 20,
804 max_vertex_buffers: 8,
805 max_vertex_attributes: 16,
806 max_vertex_buffer_array_stride: 2048,
807 max_push_constant_size: 0,
808 min_uniform_buffer_offset_alignment: 256,
809 min_storage_buffer_offset_alignment: 256,
810 max_inter_stage_shader_components: 60,
811 max_compute_workgroup_storage_size: 16352,
812 max_compute_invocations_per_workgroup: 256,
813 max_compute_workgroup_size_x: 256,
814 max_compute_workgroup_size_y: 256,
815 max_compute_workgroup_size_z: 64,
816 max_compute_workgroups_per_dimension: 65535,
817 max_buffer_size: 1 << 30,
823 /// These default limits are guarenteed to be compatible with GLES-3.1, and D3D11
824 pub fn downlevel_defaults() -> Self {
826 max_texture_dimension_1d: 2048,
827 max_texture_dimension_2d: 2048,
828 max_texture_dimension_3d: 256,
829 max_texture_array_layers: 256,
831 max_dynamic_uniform_buffers_per_pipeline_layout: 8,
832 max_dynamic_storage_buffers_per_pipeline_layout: 4,
833 max_sampled_textures_per_shader_stage: 16,
834 max_samplers_per_shader_stage: 16,
835 max_storage_buffers_per_shader_stage: 4,
836 max_storage_textures_per_shader_stage: 4,
837 max_uniform_buffers_per_shader_stage: 12,
838 max_uniform_buffer_binding_size: 16 << 10,
839 max_storage_buffer_binding_size: 128 << 20,
840 max_vertex_buffers: 8,
841 max_vertex_attributes: 16,
842 max_vertex_buffer_array_stride: 2048,
843 max_push_constant_size: 0,
844 min_uniform_buffer_offset_alignment: 256,
845 min_storage_buffer_offset_alignment: 256,
846 max_inter_stage_shader_components: 60,
847 max_compute_workgroup_storage_size: 16352,
848 max_compute_invocations_per_workgroup: 256,
849 max_compute_workgroup_size_x: 256,
850 max_compute_workgroup_size_y: 256,
851 max_compute_workgroup_size_z: 64,
852 max_compute_workgroups_per_dimension: 65535,
853 max_buffer_size: 1 << 28,
857 /// These default limits are guarenteed to be compatible with GLES-3.0, and D3D11, and WebGL2
858 pub fn downlevel_webgl2_defaults() -> Self {
860 max_uniform_buffers_per_shader_stage: 11,
861 max_storage_buffers_per_shader_stage: 0,
862 max_storage_textures_per_shader_stage: 0,
863 max_dynamic_storage_buffers_per_pipeline_layout: 0,
864 max_storage_buffer_binding_size: 0,
865 max_vertex_buffer_array_stride: 255,
866 max_compute_workgroup_storage_size: 0,
867 max_compute_invocations_per_workgroup: 0,
868 max_compute_workgroup_size_x: 0,
869 max_compute_workgroup_size_y: 0,
870 max_compute_workgroup_size_z: 0,
871 max_compute_workgroups_per_dimension: 0,
873 // Most of the values should be the same as the downlevel defaults
874 ..Self::downlevel_defaults()
878 /// Modify the current limits to use the resolution limits of the other.
880 /// This is useful because the swapchain might need to be larger than any other image in the application.
882 /// If your application only needs 512x512, you might be running on a 4k display and need extremely high resolution limits.
883 pub fn using_resolution(self, other: Self) -> Self {
885 max_texture_dimension_1d: other.max_texture_dimension_1d,
886 max_texture_dimension_2d: other.max_texture_dimension_2d,
887 max_texture_dimension_3d: other.max_texture_dimension_3d,
892 /// Modify the current limits to use the buffer alignment limits of the adapter.
894 /// This is useful for when you'd like to dynamically use the "best" supported buffer alignments.
895 pub fn using_alignment(self, other: Self) -> Self {
897 min_uniform_buffer_offset_alignment: other.min_uniform_buffer_offset_alignment,
898 min_storage_buffer_offset_alignment: other.min_storage_buffer_offset_alignment,
903 /// Compares every limits within self is within the limits given in `allowed`.
905 /// If you need detailed information on failures, look at [`Limits::check_limits_with_fail_fn`].
906 pub fn check_limits(&self, allowed: &Self) -> bool {
907 let mut within = true;
908 self.check_limits_with_fail_fn(allowed, true, |_, _, _| within = false);
912 /// Compares every limits within self is within the limits given in `allowed`.
913 /// For an easy to use binary choice, use [`Limits::check_limits`].
915 /// If a value is not within the allowed limit, this function calls the `fail_fn`
919 /// - allowed's limit.
921 /// If fatal is true, a single failure bails out the comparison after a single failure.
922 pub fn check_limits_with_fail_fn(
926 mut fail_fn: impl FnMut(&'static str, u64, u64),
928 use std::cmp::Ordering;
930 macro_rules! compare {
931 ($name:ident, $ordering:ident) => {
932 match self.$name.cmp(&allowed.$name) {
933 Ordering::$ordering | Ordering::Equal => (),
935 fail_fn(stringify!($name), self.$name as u64, allowed.$name as u64);
944 compare!(max_texture_dimension_1d, Less);
945 compare!(max_texture_dimension_2d, Less);
946 compare!(max_texture_dimension_3d, Less);
947 compare!(max_texture_array_layers, Less);
948 compare!(max_bind_groups, Less);
949 compare!(max_dynamic_uniform_buffers_per_pipeline_layout, Less);
950 compare!(max_dynamic_storage_buffers_per_pipeline_layout, Less);
951 compare!(max_sampled_textures_per_shader_stage, Less);
952 compare!(max_samplers_per_shader_stage, Less);
953 compare!(max_storage_buffers_per_shader_stage, Less);
954 compare!(max_storage_textures_per_shader_stage, Less);
955 compare!(max_uniform_buffers_per_shader_stage, Less);
956 compare!(max_uniform_buffer_binding_size, Less);
957 compare!(max_storage_buffer_binding_size, Less);
958 compare!(max_vertex_buffers, Less);
959 compare!(max_vertex_attributes, Less);
960 compare!(max_vertex_buffer_array_stride, Less);
961 compare!(max_push_constant_size, Less);
962 compare!(min_uniform_buffer_offset_alignment, Greater);
963 compare!(min_storage_buffer_offset_alignment, Greater);
964 compare!(max_inter_stage_shader_components, Less);
965 compare!(max_compute_workgroup_storage_size, Less);
966 compare!(max_compute_invocations_per_workgroup, Less);
967 compare!(max_compute_workgroup_size_x, Less);
968 compare!(max_compute_workgroup_size_y, Less);
969 compare!(max_compute_workgroup_size_z, Less);
970 compare!(max_compute_workgroups_per_dimension, Less);
971 compare!(max_buffer_size, Less);
975 /// Represents the sets of additional limits on an adapter,
976 /// which take place when running on downlevel backends.
977 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
978 pub struct DownlevelLimits {}
980 #[allow(unknown_lints)] // derivable_impls is nightly only currently
981 #[allow(clippy::derivable_impls)]
982 impl Default for DownlevelLimits {
983 fn default() -> Self {
988 /// Lists various ways the underlying platform does not conform to the WebGPU standard.
989 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
990 pub struct DownlevelCapabilities {
991 /// Combined boolean flags.
992 pub flags: DownlevelFlags,
993 /// Additional limits
994 pub limits: DownlevelLimits,
995 /// Which collections of features shaders support. Defined in terms of D3D's shader models.
996 pub shader_model: ShaderModel,
999 impl Default for DownlevelCapabilities {
1000 fn default() -> Self {
1002 flags: DownlevelFlags::all(),
1003 limits: DownlevelLimits::default(),
1004 shader_model: ShaderModel::Sm5,
1009 impl DownlevelCapabilities {
1010 /// Returns true if the underlying platform offers complete support of the baseline WebGPU standard.
1012 /// If this returns false, some parts of the API will result in validation errors where they would not normally.
1013 /// These parts can be determined by the values in this structure.
1014 pub fn is_webgpu_compliant(&self) -> bool {
1015 self.flags.contains(DownlevelFlags::compliant())
1016 && self.limits == DownlevelLimits::default()
1017 && self.shader_model >= ShaderModel::Sm5
1021 bitflags::bitflags! {
1022 /// Binary flags listing features that may or may not be present on downlevel adapters.
1024 /// A downlevel adapter is a GPU adapter that WGPU supports, but with potentially limited
1025 /// features, due to the lack of hardware feature support.
1027 /// Flags that are **not** present for a downlevel adapter or device usually indicates
1028 /// non-compliance with the WebGPU specification, but not always.
1030 /// You can check whether a set of flags is compliant through the
1031 /// [`DownlevelCapabilities::is_webgpu_compliant()`] function.
1032 pub struct DownlevelFlags: u32 {
1033 /// The device supports compiling and using compute shaders.
1035 /// DX11 on FL10 level hardware, WebGL2, and GLES3.0 devices do not support compute.
1036 const COMPUTE_SHADERS = 1 << 0;
1037 /// Supports binding storage buffers and textures to fragment shaders.
1038 const FRAGMENT_WRITABLE_STORAGE = 1 << 1;
1039 /// Supports indirect drawing and dispatching.
1041 /// DX11 on FL10 level hardware, WebGL2, and GLES 3.0 devices do not support indirect.
1042 const INDIRECT_EXECUTION = 1 << 2;
1043 /// Supports non-zero `base_vertex` parameter to indexed draw calls.
1044 const BASE_VERTEX = 1 << 3;
1045 /// Supports reading from a depth/stencil buffer while using as a read-only depth/stencil
1048 /// The WebGL2 and GLES backends do not support RODS.
1049 const READ_ONLY_DEPTH_STENCIL = 1 << 4;
1050 /// Supports textures with mipmaps which have a non power of two size.
1051 const NON_POWER_OF_TWO_MIPMAPPED_TEXTURES = 1 << 5;
1052 /// Supports textures that are cube arrays.
1053 const CUBE_ARRAY_TEXTURES = 1 << 6;
1054 /// Supports comparison samplers.
1055 const COMPARISON_SAMPLERS = 1 << 7;
1056 /// Supports different blend operations per color attachment.
1057 const INDEPENDENT_BLEND = 1 << 8;
1058 /// Supports storage buffers in vertex shaders.
1059 const VERTEX_STORAGE = 1 << 9;
1061 /// Supports samplers with anisotropic filtering. Note this isn't actually required by
1062 /// WebGPU, the implementation is allowed to completely ignore aniso clamp. This flag is
1063 /// here for native backends so they can comunicate to the user of aniso is enabled.
1065 /// All backends and all devices support anisotropic filtering.
1066 const ANISOTROPIC_FILTERING = 1 << 10;
1068 /// Supports storage buffers in fragment shaders.
1069 const FRAGMENT_STORAGE = 1 << 11;
1071 /// Supports sample-rate shading.
1072 const MULTISAMPLED_SHADING = 1 << 12;
1074 /// Supports copies between depth textures and buffers.
1076 /// GLES/WebGL don't support this.
1077 const DEPTH_TEXTURE_AND_BUFFER_COPIES = 1 << 13;
1079 /// Supports all the texture usages described in WebGPU. If this isn't supported, you
1080 /// should call `get_texture_format_features` to get how you can use textures of a given format
1081 const WEBGPU_TEXTURE_FORMAT_SUPPORT = 1 << 14;
1083 /// Supports buffer bindings with sizes that aren't a multiple of 16.
1085 /// WebGL doesn't support this.
1086 const BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED = 1 << 15;
1090 #[cfg(feature = "bitflags_serde_shim")]
1091 bitflags_serde_shim::impl_serde_for_bitflags!(DownlevelFlags);
1093 impl DownlevelFlags {
1094 /// All flags that indicate if the backend is WebGPU compliant
1095 pub const fn compliant() -> Self {
1096 // We use manual bit twiddling to make this a const fn as `Sub` and `.remove` aren't const
1098 // WebGPU doesn't actually require aniso
1099 Self::from_bits_truncate(Self::all().bits() & !Self::ANISOTROPIC_FILTERING.bits)
1103 /// Collections of shader features a device supports if they support less than WebGPU normally allows.
1104 // TODO: Fill out the differences between shader models more completely
1105 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1106 pub enum ShaderModel {
1107 /// Extremely limited shaders, including a total instruction limit.
1109 /// Missing minor features and storage images.
1111 /// WebGPU supports shader module 5.
1115 /// Supported physical device types.
1117 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
1118 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
1119 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
1120 pub enum DeviceType {
1121 /// Other or Unknown.
1123 /// Integrated GPU with shared CPU/GPU memory.
1125 /// Discrete GPU with separate CPU/GPU memory.
1127 /// Virtual / Hosted.
1129 /// Cpu / Software Rendering.
1133 //TODO: convert `vendor` and `device` to `u32`
1135 /// Information about an adapter.
1136 #[derive(Clone, Debug, Eq, PartialEq)]
1137 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
1138 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
1139 pub struct AdapterInfo {
1142 /// Vendor PCI id of the adapter
1144 /// PCI id of the adapter
1147 pub device_type: DeviceType,
1148 /// Backend used for device
1149 pub backend: Backend,
1152 /// Describes a [`Device`](../wgpu/struct.Device.html).
1154 /// Corresponds to [WebGPU `GPUDeviceDescriptor`](
1155 /// https://gpuweb.github.io/gpuweb/#gpudevicedescriptor).
1157 #[derive(Clone, Debug, Default)]
1158 #[cfg_attr(feature = "trace", derive(Serialize))]
1159 #[cfg_attr(feature = "replay", derive(Deserialize))]
1160 pub struct DeviceDescriptor<L> {
1161 /// Debug label for the device.
1163 /// Features that the device should support. If any feature is not supported by
1164 /// the adapter, creating a device will panic.
1165 pub features: Features,
1166 /// Limits that the device should support. If any limit is "better" than the limit exposed by
1167 /// the adapter, creating a device will panic.
1171 impl<L> DeviceDescriptor<L> {
1173 pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> DeviceDescriptor<K> {
1175 label: fun(&self.label),
1176 features: self.features,
1177 limits: self.limits.clone(),
1182 bitflags::bitflags! {
1183 /// Describes the shader stages that a binding will be visible from.
1185 /// These can be combined so something that is visible from both vertex and fragment shaders can be defined as:
1187 /// `ShaderStages::VERTEX | ShaderStages::FRAGMENT`
1189 /// Corresponds to [WebGPU `GPUShaderStageFlags`](
1190 /// https://gpuweb.github.io/gpuweb/#typedefdef-gpushaderstageflags).
1191 #[repr(transparent)]
1192 pub struct ShaderStages: u32 {
1193 /// Binding is not visible from any shader stage.
1195 /// Binding is visible from the vertex shader of a render pipeline.
1196 const VERTEX = 1 << 0;
1197 /// Binding is visible from the fragment shader of a render pipeline.
1198 const FRAGMENT = 1 << 1;
1199 /// Binding is visible from the compute shader of a compute pipeline.
1200 const COMPUTE = 1 << 2;
1201 /// Binding is visible from the vertex and fragment shaders of a render pipeline.
1202 const VERTEX_FRAGMENT = Self::VERTEX.bits | Self::FRAGMENT.bits;
1206 #[cfg(feature = "bitflags_serde_shim")]
1207 bitflags_serde_shim::impl_serde_for_bitflags!(ShaderStages);
1209 /// Dimensions of a particular texture view.
1211 /// Corresponds to [WebGPU `GPUTextureViewDimension`](
1212 /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureviewdimension).
1214 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1215 #[cfg_attr(feature = "trace", derive(Serialize))]
1216 #[cfg_attr(feature = "replay", derive(Deserialize))]
1217 pub enum TextureViewDimension {
1218 /// A one dimensional texture. `texture_1d` in WGSL and `texture1D` in GLSL.
1219 #[cfg_attr(feature = "serde", serde(rename = "1d"))]
1221 /// A two dimensional texture. `texture_2d` in WGSL and `texture2D` in GLSL.
1222 #[cfg_attr(feature = "serde", serde(rename = "2d"))]
1224 /// A two dimensional array texture. `texture_2d_array` in WGSL and `texture2DArray` in GLSL.
1225 #[cfg_attr(feature = "serde", serde(rename = "2d-array"))]
1227 /// A cubemap texture. `texture_cube` in WGSL and `textureCube` in GLSL.
1228 #[cfg_attr(feature = "serde", serde(rename = "cube"))]
1230 /// A cubemap array texture. `texture_cube_array` in WGSL and `textureCubeArray` in GLSL.
1231 #[cfg_attr(feature = "serde", serde(rename = "cube-array"))]
1233 /// A three dimensional texture. `texture_3d` in WGSL and `texture3D` in GLSL.
1234 #[cfg_attr(feature = "serde", serde(rename = "3d"))]
1238 impl Default for TextureViewDimension {
1239 fn default() -> Self {
1244 impl TextureViewDimension {
1245 /// Get the texture dimension required of this texture view dimension.
1246 pub fn compatible_texture_dimension(self) -> TextureDimension {
1248 Self::D1 => TextureDimension::D1,
1249 Self::D2 | Self::D2Array | Self::Cube | Self::CubeArray => TextureDimension::D2,
1250 Self::D3 => TextureDimension::D3,
1255 /// Alpha blend factor.
1257 /// Alpha blending is very complicated: see the OpenGL or Vulkan spec for more information.
1259 /// Corresponds to [WebGPU `GPUBlendFactor`](
1260 /// https://gpuweb.github.io/gpuweb/#enumdef-gpublendfactor).
1262 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1263 #[cfg_attr(feature = "trace", derive(Serialize))]
1264 #[cfg_attr(feature = "replay", derive(Deserialize))]
1265 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1266 pub enum BlendFactor {
1273 /// 1.0 - S.component
1278 OneMinusSrcAlpha = 5,
1281 /// 1.0 - D.component
1286 OneMinusDstAlpha = 9,
1287 /// min(S.alpha, 1.0 - D.alpha)
1288 SrcAlphaSaturated = 10,
1292 OneMinusConstant = 12,
1295 /// Alpha blend operation.
1297 /// Alpha blending is very complicated: see the OpenGL or Vulkan spec for more information.
1299 /// Corresponds to [WebGPU `GPUBlendOperation`](
1300 /// https://gpuweb.github.io/gpuweb/#enumdef-gpublendoperation).
1302 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1303 #[cfg_attr(feature = "trace", derive(Serialize))]
1304 #[cfg_attr(feature = "replay", derive(Deserialize))]
1305 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1306 pub enum BlendOperation {
1312 ReverseSubtract = 2,
1319 impl Default for BlendOperation {
1320 fn default() -> Self {
1325 /// Describes a blend component of a [`BlendState`].
1327 /// Corresponds to [WebGPU `GPUBlendComponent`](
1328 /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendcomponent).
1330 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1331 #[cfg_attr(feature = "trace", derive(Serialize))]
1332 #[cfg_attr(feature = "replay", derive(Deserialize))]
1333 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1334 pub struct BlendComponent {
1335 /// Multiplier for the source, which is produced by the fragment shader.
1336 pub src_factor: BlendFactor,
1337 /// Multiplier for the destination, which is stored in the target.
1338 pub dst_factor: BlendFactor,
1339 /// The binary operation applied to the source and destination,
1340 /// multiplied by their respective factors.
1341 pub operation: BlendOperation,
1344 impl BlendComponent {
1345 /// Default blending state that replaces destination with the source.
1346 pub const REPLACE: Self = Self {
1347 src_factor: BlendFactor::One,
1348 dst_factor: BlendFactor::Zero,
1349 operation: BlendOperation::Add,
1352 /// Blend state of (1 * src) + ((1 - src_alpha) * dst)
1353 pub const OVER: Self = Self {
1354 src_factor: BlendFactor::One,
1355 dst_factor: BlendFactor::OneMinusSrcAlpha,
1356 operation: BlendOperation::Add,
1359 /// Returns true if the state relies on the constant color, which is
1360 /// set independently on a render command encoder.
1361 pub fn uses_constant(&self) -> bool {
1362 match (self.src_factor, self.dst_factor) {
1363 (BlendFactor::Constant, _)
1364 | (BlendFactor::OneMinusConstant, _)
1365 | (_, BlendFactor::Constant)
1366 | (_, BlendFactor::OneMinusConstant) => true,
1372 impl Default for BlendComponent {
1373 fn default() -> Self {
1378 /// Describe the blend state of a render pipeline,
1379 /// within [`ColorTargetState`].
1381 /// See the OpenGL or Vulkan spec for more information.
1383 /// Corresponds to [WebGPU `GPUBlendState`](
1384 /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendstate).
1386 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1387 #[cfg_attr(feature = "trace", derive(Serialize))]
1388 #[cfg_attr(feature = "replay", derive(Deserialize))]
1389 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1390 pub struct BlendState {
1392 pub color: BlendComponent,
1394 pub alpha: BlendComponent,
1398 /// Blend mode that does no color blending, just overwrites the output with the contents of the shader.
1399 pub const REPLACE: Self = Self {
1400 color: BlendComponent::REPLACE,
1401 alpha: BlendComponent::REPLACE,
1404 /// Blend mode that does standard alpha blending with non-premultiplied alpha.
1405 pub const ALPHA_BLENDING: Self = Self {
1406 color: BlendComponent {
1407 src_factor: BlendFactor::SrcAlpha,
1408 dst_factor: BlendFactor::OneMinusSrcAlpha,
1409 operation: BlendOperation::Add,
1411 alpha: BlendComponent::OVER,
1414 /// Blend mode that does standard alpha blending with premultiplied alpha.
1415 pub const PREMULTIPLIED_ALPHA_BLENDING: Self = Self {
1416 color: BlendComponent::OVER,
1417 alpha: BlendComponent::OVER,
1421 /// Describes the color state of a render pipeline.
1423 /// Corresponds to [WebGPU `GPUColorTargetState`](
1424 /// https://gpuweb.github.io/gpuweb/#dictdef-gpucolortargetstate).
1426 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
1427 #[cfg_attr(feature = "trace", derive(Serialize))]
1428 #[cfg_attr(feature = "replay", derive(Deserialize))]
1429 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1430 pub struct ColorTargetState {
1431 /// The [`TextureFormat`] of the image that this pipeline will render to. Must match the the format
1432 /// of the corresponding color attachment in [`CommandEncoder::begin_render_pass`][CEbrp]
1434 /// [CEbrp]: ../wgpu/struct.CommandEncoder.html#method.begin_render_pass
1435 pub format: TextureFormat,
1436 /// The blending that is used for this pipeline.
1437 #[cfg_attr(feature = "serde", serde(default))]
1438 pub blend: Option<BlendState>,
1439 /// Mask which enables/disables writes to different color/alpha channel.
1440 #[cfg_attr(feature = "serde", serde(default))]
1441 pub write_mask: ColorWrites,
1444 impl From<TextureFormat> for ColorTargetState {
1445 fn from(format: TextureFormat) -> Self {
1449 write_mask: ColorWrites::ALL,
1454 /// Primitive type the input mesh is composed of.
1456 /// Corresponds to [WebGPU `GPUPrimitiveTopology`](
1457 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuprimitivetopology).
1459 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1460 #[cfg_attr(feature = "trace", derive(Serialize))]
1461 #[cfg_attr(feature = "replay", derive(Deserialize))]
1462 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1463 pub enum PrimitiveTopology {
1464 /// Vertex data is a list of points. Each vertex is a new point.
1466 /// Vertex data is a list of lines. Each pair of vertices composes a new line.
1468 /// Vertices `0 1 2 3` create two lines `0 1` and `2 3`
1470 /// Vertex data is a strip of lines. Each set of two adjacent vertices form a line.
1472 /// Vertices `0 1 2 3` create three lines `0 1`, `1 2`, and `2 3`.
1474 /// Vertex data is a list of triangles. Each set of 3 vertices composes a new triangle.
1476 /// Vertices `0 1 2 3 4 5` create two triangles `0 1 2` and `3 4 5`
1478 /// Vertex data is a triangle strip. Each set of three adjacent vertices form a triangle.
1480 /// Vertices `0 1 2 3 4 5` creates four triangles `0 1 2`, `2 1 3`, `2 3 4`, and `4 3 5`
1484 impl Default for PrimitiveTopology {
1485 fn default() -> Self {
1486 PrimitiveTopology::TriangleList
1490 impl PrimitiveTopology {
1491 /// Returns true for strip topologies.
1492 pub fn is_strip(&self) -> bool {
1494 Self::PointList | Self::LineList | Self::TriangleList => false,
1495 Self::LineStrip | Self::TriangleStrip => true,
1500 /// Vertex winding order which classifies the "front" face of a triangle.
1502 /// Corresponds to [WebGPU `GPUFrontFace`](
1503 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufrontface).
1505 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1506 #[cfg_attr(feature = "trace", derive(Serialize))]
1507 #[cfg_attr(feature = "replay", derive(Deserialize))]
1508 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1509 pub enum FrontFace {
1510 /// Triangles with vertices in counter clockwise order are considered the front face.
1512 /// This is the default with right handed coordinate spaces.
1514 /// Triangles with vertices in clockwise order are considered the front face.
1516 /// This is the default with left handed coordinate spaces.
1520 impl Default for FrontFace {
1521 fn default() -> Self {
1526 /// Face of a vertex.
1528 /// Corresponds to [WebGPU `GPUCullMode`](
1529 /// https://gpuweb.github.io/gpuweb/#enumdef-gpucullmode),
1530 /// except that the `"none"` value is represented using `Option<Face>` instead.
1532 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1533 #[cfg_attr(feature = "trace", derive(Serialize))]
1534 #[cfg_attr(feature = "replay", derive(Deserialize))]
1535 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1543 /// Type of drawing mode for polygons
1545 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1546 #[cfg_attr(feature = "trace", derive(Serialize))]
1547 #[cfg_attr(feature = "replay", derive(Deserialize))]
1548 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1549 pub enum PolygonMode {
1550 /// Polygons are filled
1552 /// Polygons are drawn as line segments
1554 /// Polygons are drawn as points
1558 impl Default for PolygonMode {
1559 fn default() -> Self {
1564 /// Describes the state of primitive assembly and rasterization in a render pipeline.
1566 /// Corresponds to [WebGPU `GPUPrimitiveState`](
1567 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuprimitivestate).
1569 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1570 #[cfg_attr(feature = "trace", derive(Serialize))]
1571 #[cfg_attr(feature = "replay", derive(Deserialize))]
1572 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1573 pub struct PrimitiveState {
1574 /// The primitive topology used to interpret vertices.
1575 pub topology: PrimitiveTopology,
1576 /// When drawing strip topologies with indices, this is the required format for the index buffer.
1577 /// This has no effect on non-indexed or non-strip draws.
1578 #[cfg_attr(feature = "serde", serde(default))]
1579 pub strip_index_format: Option<IndexFormat>,
1580 /// The face to consider the front for the purpose of culling and stencil operations.
1581 #[cfg_attr(feature = "serde", serde(default))]
1582 pub front_face: FrontFace,
1583 /// The face culling mode.
1584 #[cfg_attr(feature = "serde", serde(default))]
1585 pub cull_mode: Option<Face>,
1586 /// If set to true, the polygon depth is not clipped to 0-1 before rasterization.
1588 /// Enabling this requires `Features::DEPTH_CLIP_CONTROL` to be enabled.
1589 #[cfg_attr(feature = "serde", serde(default))]
1590 pub unclipped_depth: bool,
1591 /// Controls the way each polygon is rasterized. Can be either `Fill` (default), `Line` or `Point`
1593 /// Setting this to `Line` requires `Features::POLYGON_MODE_LINE` to be enabled.
1595 /// Setting this to `Point` requires `Features::POLYGON_MODE_POINT` to be enabled.
1596 #[cfg_attr(feature = "serde", serde(default))]
1597 pub polygon_mode: PolygonMode,
1598 /// If set to true, the primitives are rendered with conservative overestimation. I.e. any rastered pixel touched by it is filled.
1599 /// Only valid for PolygonMode::Fill!
1601 /// Enabling this requires `Features::CONSERVATIVE_RASTERIZATION` to be enabled.
1602 pub conservative: bool,
1605 /// Describes the multi-sampling state of a render pipeline.
1607 /// Corresponds to [WebGPU `GPUMultisampleState`](
1608 /// https://gpuweb.github.io/gpuweb/#dictdef-gpumultisamplestate).
1610 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1611 #[cfg_attr(feature = "trace", derive(Serialize))]
1612 #[cfg_attr(feature = "replay", derive(Deserialize))]
1613 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1614 pub struct MultisampleState {
1615 /// The number of samples calculated per pixel (for MSAA). For non-multisampled textures,
1616 /// this should be `1`
1618 /// Bitmask that restricts the samples of a pixel modified by this pipeline. All samples
1619 /// can be enabled using the value `!0`
1621 /// When enabled, produces another sample mask per pixel based on the alpha output value, that
1622 /// is ANDed with the sample_mask and the primitive coverage to restrict the set of samples
1623 /// affected by a primitive.
1625 /// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one
1626 /// is guaranteed to be all 1-s.
1627 pub alpha_to_coverage_enabled: bool,
1630 impl Default for MultisampleState {
1631 fn default() -> Self {
1635 alpha_to_coverage_enabled: false,
1640 bitflags::bitflags! {
1641 /// Feature flags for a texture format.
1642 #[repr(transparent)]
1643 pub struct TextureFormatFeatureFlags: u32 {
1644 /// If not present, the texture can't be sampled with a filtering sampler.
1645 /// This may overwrite TextureSampleType::Float.filterable
1646 const FILTERABLE = 1 << 0;
1647 /// Allows [`TextureDescriptor::sample_count`] greater than `1`.
1648 const MULTISAMPLE = 1 << 1;
1649 /// Allows a texture of this format to back a view passed as `resolve_target`
1650 /// to a render pass for an automatic driver-implemented resolve.
1651 const MULTISAMPLE_RESOLVE = 1 << 2;
1652 /// When used as a STORAGE texture, then a texture with this format can be bound with
1653 /// [`StorageTextureAccess::ReadOnly`] or [`StorageTextureAccess::ReadWrite`].
1654 const STORAGE_READ_WRITE = 1 << 3;
1655 /// When used as a STORAGE texture, then a texture with this format can be written to with atomics.
1656 // TODO: No access flag exposed as of writing
1657 const STORAGE_ATOMICS = 1 << 4;
1661 #[cfg(feature = "bitflags_serde_shim")]
1662 bitflags_serde_shim::impl_serde_for_bitflags!(TextureFormatFeatureFlags);
1664 /// Features supported by a given texture format
1666 /// Features are defined by WebGPU specification unless `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled.
1667 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1668 pub struct TextureFormatFeatures {
1669 /// Valid bits for `TextureDescriptor::Usage` provided for format creation.
1670 pub allowed_usages: TextureUsages,
1671 /// Additional property flags for the format.
1672 pub flags: TextureFormatFeatureFlags,
1675 /// Information about a texture format.
1676 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1677 pub struct TextureFormatInfo {
1678 /// Features required (if any) to use the texture.
1679 pub required_features: Features,
1680 /// Type of sampling that is valid for the texture.
1681 pub sample_type: TextureSampleType,
1682 /// Dimension of a "block" of texels. This is always (1, 1) on uncompressed textures.
1683 pub block_dimensions: (u8, u8),
1684 /// Size in bytes of a "block" of texels. This is the size per pixel on uncompressed textures.
1686 /// Count of components in the texture. This determines which components there will be actual data in the shader for.
1688 /// Format will have colors be converted from srgb to linear on read and from linear to srgb on write.
1690 /// Format features guaranteed by the WebGPU spec. Additional features are available if `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled.
1691 pub guaranteed_format_features: TextureFormatFeatures,
1694 impl TextureFormatInfo {
1695 /// Return `true` for compressed formats.
1696 pub fn is_compressed(&self) -> bool {
1697 self.block_dimensions != (1, 1)
1701 /// ASTC block dimensions
1703 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1704 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1705 pub enum AstcBlock {
1706 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px).
1708 /// 5x4 block compressed texture. 16 bytes per block (6.4 bit/px).
1710 /// 5x5 block compressed texture. 16 bytes per block (5.12 bit/px).
1712 /// 6x5 block compressed texture. 16 bytes per block (4.27 bit/px).
1714 /// 6x6 block compressed texture. 16 bytes per block (3.56 bit/px).
1716 /// 8x5 block compressed texture. 16 bytes per block (3.2 bit/px).
1718 /// 8x6 block compressed texture. 16 bytes per block (2.67 bit/px).
1720 /// 8x8 block compressed texture. 16 bytes per block (2 bit/px).
1722 /// 10x5 block compressed texture. 16 bytes per block (2.56 bit/px).
1724 /// 10x6 block compressed texture. 16 bytes per block (2.13 bit/px).
1726 /// 10x8 block compressed texture. 16 bytes per block (1.6 bit/px).
1728 /// 10x10 block compressed texture. 16 bytes per block (1.28 bit/px).
1730 /// 12x10 block compressed texture. 16 bytes per block (1.07 bit/px).
1732 /// 12x12 block compressed texture. 16 bytes per block (0.89 bit/px).
1736 /// ASTC RGBA channel
1738 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1739 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1740 pub enum AstcChannel {
1741 /// 8 bit integer RGBA, [0, 255] converted to/from linear-color float [0, 1] in shader.
1743 /// [`Features::TEXTURE_COMPRESSION_ASTC_LDR`] must be enabled to use this channel.
1745 /// 8 bit integer RGBA, Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
1747 /// [`Features::TEXTURE_COMPRESSION_ASTC_LDR`] must be enabled to use this channel.
1749 /// floating-point RGBA, linear-color float can be outside of the [0, 1] range.
1751 /// [`Features::TEXTURE_COMPRESSION_ASTC_HDR`] must be enabled to use this channel.
1755 /// Underlying texture data format.
1757 /// If there is a conversion in the format (such as srgb -> linear), the conversion listed here is for
1758 /// loading from texture in a shader. When writing to the texture, the opposite conversion takes place.
1760 /// Corresponds to [WebGPU `GPUTextureFormat`](
1761 /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureformat).
1763 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1764 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1765 pub enum TextureFormat {
1766 // Normal 8 bit formats
1767 /// Red channel only. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1768 #[cfg_attr(feature = "serde", serde(rename = "r8unorm"))]
1770 /// Red channel only. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.
1771 #[cfg_attr(feature = "serde", serde(rename = "r8snorm"))]
1773 /// Red channel only. 8 bit integer per channel. Unsigned in shader.
1774 #[cfg_attr(feature = "serde", serde(rename = "r8uint"))]
1776 /// Red channel only. 8 bit integer per channel. Signed in shader.
1777 #[cfg_attr(feature = "serde", serde(rename = "r8sint"))]
1780 // Normal 16 bit formats
1781 /// Red channel only. 16 bit integer per channel. Unsigned in shader.
1782 #[cfg_attr(feature = "serde", serde(rename = "r16uint"))]
1784 /// Red channel only. 16 bit integer per channel. Signed in shader.
1785 #[cfg_attr(feature = "serde", serde(rename = "r16sint"))]
1787 /// Red channel only. 16 bit integer per channel. [0, 65535] converted to/from float [0, 1] in shader.
1789 /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1790 #[cfg_attr(feature = "serde", serde(rename = "r16unorm"))]
1792 /// Red channel only. 16 bit integer per channel. [0, 65535] converted to/from float [-1, 1] in shader.
1794 /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1795 #[cfg_attr(feature = "serde", serde(rename = "r16snorm"))]
1797 /// Red channel only. 16 bit float per channel. Float in shader.
1798 #[cfg_attr(feature = "serde", serde(rename = "r16float"))]
1800 /// Red and green channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1801 #[cfg_attr(feature = "serde", serde(rename = "rg8unorm"))]
1803 /// Red and green channels. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.
1804 #[cfg_attr(feature = "serde", serde(rename = "rg8snorm"))]
1806 /// Red and green channels. 8 bit integer per channel. Unsigned in shader.
1807 #[cfg_attr(feature = "serde", serde(rename = "rg8uint"))]
1809 /// Red and green channels. 8 bit integer per channel. Signed in shader.
1810 #[cfg_attr(feature = "serde", serde(rename = "rg8sint"))]
1813 // Normal 32 bit formats
1814 /// Red channel only. 32 bit integer per channel. Unsigned in shader.
1815 #[cfg_attr(feature = "serde", serde(rename = "r32uint"))]
1817 /// Red channel only. 32 bit integer per channel. Signed in shader.
1818 #[cfg_attr(feature = "serde", serde(rename = "r32sint"))]
1820 /// Red channel only. 32 bit float per channel. Float in shader.
1821 #[cfg_attr(feature = "serde", serde(rename = "r32float"))]
1823 /// Red and green channels. 16 bit integer per channel. Unsigned in shader.
1824 #[cfg_attr(feature = "serde", serde(rename = "rg16uint"))]
1826 /// Red and green channels. 16 bit integer per channel. Signed in shader.
1827 #[cfg_attr(feature = "serde", serde(rename = "rg16sint"))]
1829 /// Red and green channels. 16 bit integer per channel. [0, 65535] converted to/from float [0, 1] in shader.
1831 /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1832 #[cfg_attr(feature = "serde", serde(rename = "rg16unorm"))]
1834 /// Red and green channels. 16 bit integer per channel. [0, 65535] converted to/from float [-1, 1] in shader.
1836 /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1837 #[cfg_attr(feature = "serde", serde(rename = "rg16snorm"))]
1839 /// Red and green channels. 16 bit float per channel. Float in shader.
1840 #[cfg_attr(feature = "serde", serde(rename = "rg16float"))]
1842 /// Red, green, blue, and alpha channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1843 #[cfg_attr(feature = "serde", serde(rename = "rgba8unorm"))]
1845 /// Red, green, blue, and alpha channels. 8 bit integer per channel. Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
1846 #[cfg_attr(feature = "serde", serde(rename = "rgba8unorm-srgb"))]
1848 /// Red, green, blue, and alpha channels. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.
1849 #[cfg_attr(feature = "serde", serde(rename = "rgba8snorm"))]
1851 /// Red, green, blue, and alpha channels. 8 bit integer per channel. Unsigned in shader.
1852 #[cfg_attr(feature = "serde", serde(rename = "rgba8uint"))]
1854 /// Red, green, blue, and alpha channels. 8 bit integer per channel. Signed in shader.
1855 #[cfg_attr(feature = "serde", serde(rename = "rgba8sint"))]
1857 /// Blue, green, red, and alpha channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1858 #[cfg_attr(feature = "serde", serde(rename = "bgra8unorm"))]
1860 /// Blue, green, red, and alpha channels. 8 bit integer per channel. Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
1861 #[cfg_attr(feature = "serde", serde(rename = "bgra8unorm-srgb"))]
1864 // Packed 32 bit formats
1865 /// Red, green, blue, and alpha channels. 10 bit integer for RGB channels, 2 bit integer for alpha channel. [0, 1023] ([0, 3] for alpha) converted to/from float [0, 1] in shader.
1866 #[cfg_attr(feature = "serde", serde(rename = "rgb10a2unorm"))]
1868 /// Red, green, and blue channels. 11 bit float with no sign bit for RG channels. 10 bit float with no sign bit for blue channel. Float in shader.
1869 #[cfg_attr(feature = "serde", serde(rename = "rg11b10ufloat"))]
1872 // Normal 64 bit formats
1873 /// Red and green channels. 32 bit integer per channel. Unsigned in shader.
1874 #[cfg_attr(feature = "serde", serde(rename = "rg32uint"))]
1876 /// Red and green channels. 32 bit integer per channel. Signed in shader.
1877 #[cfg_attr(feature = "serde", serde(rename = "rg32sint"))]
1879 /// Red and green channels. 32 bit float per channel. Float in shader.
1880 #[cfg_attr(feature = "serde", serde(rename = "rg32float"))]
1882 /// Red, green, blue, and alpha channels. 16 bit integer per channel. Unsigned in shader.
1883 #[cfg_attr(feature = "serde", serde(rename = "rgba16uint"))]
1885 /// Red, green, blue, and alpha channels. 16 bit integer per channel. Signed in shader.
1886 #[cfg_attr(feature = "serde", serde(rename = "rgba16sint"))]
1888 /// Red, green, blue, and alpha channels. 16 bit integer per channel. [0, 65535] converted to/from float [0, 1] in shader.
1890 /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1891 #[cfg_attr(feature = "serde", serde(rename = "rgba16unorm"))]
1893 /// Red, green, blue, and alpha. 16 bit integer per channel. [0, 65535] converted to/from float [-1, 1] in shader.
1895 /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1896 #[cfg_attr(feature = "serde", serde(rename = "rgba16snorm"))]
1898 /// Red, green, blue, and alpha channels. 16 bit float per channel. Float in shader.
1899 #[cfg_attr(feature = "serde", serde(rename = "rgba16float"))]
1902 // Normal 128 bit formats
1903 /// Red, green, blue, and alpha channels. 32 bit integer per channel. Unsigned in shader.
1904 #[cfg_attr(feature = "serde", serde(rename = "rgba32uint"))]
1906 /// Red, green, blue, and alpha channels. 32 bit integer per channel. Signed in shader.
1907 #[cfg_attr(feature = "serde", serde(rename = "rgba32sint"))]
1909 /// Red, green, blue, and alpha channels. 32 bit float per channel. Float in shader.
1910 #[cfg_attr(feature = "serde", serde(rename = "rgba32float"))]
1913 // Depth and stencil formats
1914 /// Special depth format with 32 bit floating point depth.
1915 #[cfg_attr(feature = "serde", serde(rename = "depth32float"))]
1917 /// Special depth/stencil format with 32 bit floating point depth and 8 bits integer stencil.
1918 #[cfg_attr(feature = "serde", serde(rename = "depth32float-stencil8"))]
1919 Depth32FloatStencil8,
1920 /// Special depth format with at least 24 bit integer depth.
1921 #[cfg_attr(feature = "serde", serde(rename = "depth24plus"))]
1923 /// Special depth/stencil format with at least 24 bit integer depth and 8 bits integer stencil.
1924 #[cfg_attr(feature = "serde", serde(rename = "depth24plus-stencil8"))]
1925 Depth24PlusStencil8,
1926 /// Special depth/stencil format with 24 bit integer depth and 8 bits integer stencil.
1927 #[cfg_attr(feature = "serde", serde(rename = "depth24unorm-stencil8"))]
1928 Depth24UnormStencil8,
1930 // Packed uncompressed texture formats
1931 /// Packed unsigned float with 9 bits mantisa for each RGB component, then a common 5 bits exponent
1932 #[cfg_attr(feature = "serde", serde(rename = "rgb9e5ufloat"))]
1935 // Compressed textures usable with `TEXTURE_COMPRESSION_BC` feature.
1936 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 4 color + alpha pallet. 5 bit R + 6 bit G + 5 bit B + 1 bit alpha.
1937 /// [0, 63] ([0, 1] for alpha) converted to/from float [0, 1] in shader.
1939 /// Also known as DXT1.
1941 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1942 #[cfg_attr(feature = "serde", serde(rename = "bc1-rgba-unorm"))]
1944 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 4 color + alpha pallet. 5 bit R + 6 bit G + 5 bit B + 1 bit alpha.
1945 /// Srgb-color [0, 63] ([0, 1] for alpha) converted to/from linear-color float [0, 1] in shader.
1947 /// Also known as DXT1.
1949 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1950 #[cfg_attr(feature = "serde", serde(rename = "bc1-rgba-unorm-srgb"))]
1952 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet. 5 bit R + 6 bit G + 5 bit B + 4 bit alpha.
1953 /// [0, 63] ([0, 15] for alpha) converted to/from float [0, 1] in shader.
1955 /// Also known as DXT3.
1957 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1958 #[cfg_attr(feature = "serde", serde(rename = "bc2-rgba-unorm"))]
1960 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet. 5 bit R + 6 bit G + 5 bit B + 4 bit alpha.
1961 /// Srgb-color [0, 63] ([0, 255] for alpha) converted to/from linear-color float [0, 1] in shader.
1963 /// Also known as DXT3.
1965 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1966 #[cfg_attr(feature = "serde", serde(rename = "bc2-rgba-unorm-srgb"))]
1968 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet + 8 alpha pallet. 5 bit R + 6 bit G + 5 bit B + 8 bit alpha.
1969 /// [0, 63] ([0, 255] for alpha) converted to/from float [0, 1] in shader.
1971 /// Also known as DXT5.
1973 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1974 #[cfg_attr(feature = "serde", serde(rename = "bc3-rgba-unorm"))]
1976 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet + 8 alpha pallet. 5 bit R + 6 bit G + 5 bit B + 8 bit alpha.
1977 /// Srgb-color [0, 63] ([0, 255] for alpha) converted to/from linear-color float [0, 1] in shader.
1979 /// Also known as DXT5.
1981 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1982 #[cfg_attr(feature = "serde", serde(rename = "bc3-rgba-unorm-srgb"))]
1984 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 8 color pallet. 8 bit R.
1985 /// [0, 255] converted to/from float [0, 1] in shader.
1987 /// Also known as RGTC1.
1989 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1990 #[cfg_attr(feature = "serde", serde(rename = "bc4-r-unorm"))]
1992 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 8 color pallet. 8 bit R.
1993 /// [-127, 127] converted to/from float [-1, 1] in shader.
1995 /// Also known as RGTC1.
1997 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1998 #[cfg_attr(feature = "serde", serde(rename = "bc4-r-snorm"))]
2000 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 8 color red pallet + 8 color green pallet. 8 bit RG.
2001 /// [0, 255] converted to/from float [0, 1] in shader.
2003 /// Also known as RGTC2.
2005 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2006 #[cfg_attr(feature = "serde", serde(rename = "bc5-rg-unorm"))]
2008 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 8 color red pallet + 8 color green pallet. 8 bit RG.
2009 /// [-127, 127] converted to/from float [-1, 1] in shader.
2011 /// Also known as RGTC2.
2013 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2014 #[cfg_attr(feature = "serde", serde(rename = "bc5-rg-snorm"))]
2016 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 16 bit unsigned float RGB. Float in shader.
2018 /// Also known as BPTC (float).
2020 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2021 #[cfg_attr(feature = "serde", serde(rename = "bc6h-rgb-ufloat"))]
2023 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 16 bit signed float RGB. Float in shader.
2025 /// Also known as BPTC (float).
2027 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2028 #[cfg_attr(feature = "serde", serde(rename = "bc6h-rgb-float"))]
2030 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 8 bit integer RGBA.
2031 /// [0, 255] converted to/from float [0, 1] in shader.
2033 /// Also known as BPTC (unorm).
2035 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2036 #[cfg_attr(feature = "serde", serde(rename = "bc7-rgba-unorm"))]
2038 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 8 bit integer RGBA.
2039 /// Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
2041 /// Also known as BPTC (unorm).
2043 /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2044 #[cfg_attr(feature = "serde", serde(rename = "bc7-rgba-unorm-srgb"))]
2046 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB.
2047 /// [0, 255] converted to/from float [0, 1] in shader.
2049 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2050 #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8unorm"))]
2052 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB.
2053 /// Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
2055 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2056 #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8unorm-srgb"))]
2058 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB + 1 bit alpha.
2059 /// [0, 255] ([0, 1] for alpha) converted to/from float [0, 1] in shader.
2061 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2062 #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8a1unorm"))]
2064 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB + 1 bit alpha.
2065 /// Srgb-color [0, 255] ([0, 1] for alpha) converted to/from linear-color float [0, 1] in shader.
2067 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2068 #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8a1unorm-srgb"))]
2069 Etc2Rgb8A1UnormSrgb,
2070 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGB + 8 bit alpha.
2071 /// [0, 255] converted to/from float [0, 1] in shader.
2073 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2074 #[cfg_attr(feature = "serde", serde(rename = "etc2-rgba8unorm"))]
2076 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGB + 8 bit alpha.
2077 /// Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
2079 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2080 #[cfg_attr(feature = "serde", serde(rename = "etc2-rgba8unorm-srgb"))]
2082 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 11 bit integer R.
2083 /// [0, 255] converted to/from float [0, 1] in shader.
2085 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2086 #[cfg_attr(feature = "serde", serde(rename = "eac-r11unorm"))]
2088 /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 11 bit integer R.
2089 /// [-127, 127] converted to/from float [-1, 1] in shader.
2091 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2092 #[cfg_attr(feature = "serde", serde(rename = "eac-r11snorm"))]
2094 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 11 bit integer R + 11 bit integer G.
2095 /// [0, 255] converted to/from float [0, 1] in shader.
2097 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2098 #[cfg_attr(feature = "serde", serde(rename = "eac-rg11unorm"))]
2100 /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 11 bit integer R + 11 bit integer G.
2101 /// [-127, 127] converted to/from float [-1, 1] in shader.
2103 /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2104 #[cfg_attr(feature = "serde", serde(rename = "eac-rg11snorm"))]
2106 /// block compressed texture. 16 bytes per block.
2108 /// Features [`TEXTURE_COMPRESSION_ASTC_LDR`] or [`TEXTURE_COMPRESSION_ASTC_HDR`]
2109 /// must be enabled to use this texture format.
2111 /// [`TEXTURE_COMPRESSION_ASTC_LDR`]: Features::TEXTURE_COMPRESSION_ASTC_LDR
2112 /// [`TEXTURE_COMPRESSION_ASTC_HDR`]: Features::TEXTURE_COMPRESSION_ASTC_HDR
2114 /// compressed block dimensions
2117 channel: AstcChannel,
2121 impl TextureFormat {
2122 /// Get useful information about the texture format.
2123 pub fn describe(&self) -> TextureFormatInfo {
2125 let native = Features::empty();
2126 let bc = Features::TEXTURE_COMPRESSION_BC;
2127 let etc2 = Features::TEXTURE_COMPRESSION_ETC2;
2128 let astc_ldr = Features::TEXTURE_COMPRESSION_ASTC_LDR;
2129 let astc_hdr = Features::TEXTURE_COMPRESSION_ASTC_HDR;
2130 let norm16bit = Features::TEXTURE_FORMAT_16BIT_NORM;
2131 let d32_s8 = Features::DEPTH32FLOAT_STENCIL8;
2132 let d24_s8 = Features::DEPTH24UNORM_STENCIL8;
2135 let uint = TextureSampleType::Uint;
2136 let sint = TextureSampleType::Sint;
2137 let nearest = TextureSampleType::Float { filterable: false };
2138 let float = TextureSampleType::Float { filterable: true };
2139 let depth = TextureSampleType::Depth;
2145 let linear = ColorSpace::Linear;
2146 let corrected = ColorSpace::Corrected;
2149 let noaa = TextureFormatFeatureFlags::empty();
2150 let msaa = TextureFormatFeatureFlags::MULTISAMPLE;
2152 TextureFormatFeatureFlags::MULTISAMPLE | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE;
2156 TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING;
2157 let attachment = basic | TextureUsages::RENDER_ATTACHMENT;
2158 let storage = basic | TextureUsages::STORAGE_BINDING;
2159 let all_flags = TextureUsages::all();
2161 // See <https://gpuweb.github.io/gpuweb/#texture-format-caps> for reference
2162 #[rustfmt::skip] // lets make a nice table
2173 // Normal 8 bit textures
2174 Self::R8Unorm => ( native, float, linear, msaa_resolve, (1, 1), 1, attachment, 1),
2175 Self::R8Snorm => ( native, float, linear, msaa, (1, 1), 1, basic, 1),
2176 Self::R8Uint => ( native, uint, linear, msaa, (1, 1), 1, attachment, 1),
2177 Self::R8Sint => ( native, sint, linear, msaa, (1, 1), 1, attachment, 1),
2179 // Normal 16 bit textures
2180 Self::R16Uint => ( native, uint, linear, msaa, (1, 1), 2, attachment, 1),
2181 Self::R16Sint => ( native, sint, linear, msaa, (1, 1), 2, attachment, 1),
2182 Self::R16Float => ( native, float, linear, msaa_resolve, (1, 1), 2, attachment, 1),
2183 Self::Rg8Unorm => ( native, float, linear, msaa_resolve, (1, 1), 2, attachment, 2),
2184 Self::Rg8Snorm => ( native, float, linear, msaa, (1, 1), 2, attachment, 2),
2185 Self::Rg8Uint => ( native, uint, linear, msaa, (1, 1), 2, attachment, 2),
2186 Self::Rg8Sint => ( native, sint, linear, msaa, (1, 1), 2, basic, 2),
2188 // Normal 32 bit textures
2189 Self::R32Uint => ( native, uint, linear, noaa, (1, 1), 4, all_flags, 1),
2190 Self::R32Sint => ( native, sint, linear, noaa, (1, 1), 4, all_flags, 1),
2191 Self::R32Float => ( native, nearest, linear, msaa, (1, 1), 4, all_flags, 1),
2192 Self::Rg16Uint => ( native, uint, linear, msaa, (1, 1), 4, attachment, 2),
2193 Self::Rg16Sint => ( native, sint, linear, msaa, (1, 1), 4, attachment, 2),
2194 Self::Rg16Float => ( native, float, linear, msaa_resolve, (1, 1), 4, attachment, 2),
2195 Self::Rgba8Unorm => ( native, float, linear, msaa_resolve, (1, 1), 4, all_flags, 4),
2196 Self::Rgba8UnormSrgb => ( native, float, corrected, msaa_resolve, (1, 1), 4, attachment, 4),
2197 Self::Rgba8Snorm => ( native, float, linear, msaa, (1, 1), 4, storage, 4),
2198 Self::Rgba8Uint => ( native, uint, linear, msaa, (1, 1), 4, all_flags, 4),
2199 Self::Rgba8Sint => ( native, sint, linear, msaa, (1, 1), 4, all_flags, 4),
2200 Self::Bgra8Unorm => ( native, float, linear, msaa_resolve, (1, 1), 4, attachment, 4),
2201 Self::Bgra8UnormSrgb => ( native, float, corrected, msaa_resolve, (1, 1), 4, attachment, 4),
2203 // Packed 32 bit textures
2204 Self::Rgb10a2Unorm => ( native, float, linear, msaa_resolve, (1, 1), 4, attachment, 4),
2205 Self::Rg11b10Float => ( native, float, linear, msaa, (1, 1), 4, basic, 3),
2207 // Packed 32 bit textures
2208 Self::Rg32Uint => ( native, uint, linear, noaa, (1, 1), 8, all_flags, 2),
2209 Self::Rg32Sint => ( native, sint, linear, noaa, (1, 1), 8, all_flags, 2),
2210 Self::Rg32Float => ( native, nearest, linear, noaa, (1, 1), 8, all_flags, 2),
2211 Self::Rgba16Uint => ( native, uint, linear, msaa, (1, 1), 8, all_flags, 4),
2212 Self::Rgba16Sint => ( native, sint, linear, msaa, (1, 1), 8, all_flags, 4),
2213 Self::Rgba16Float => ( native, float, linear, msaa_resolve, (1, 1), 8, all_flags, 4),
2215 // Packed 32 bit textures
2216 Self::Rgba32Uint => ( native, uint, linear, noaa, (1, 1), 16, all_flags, 4),
2217 Self::Rgba32Sint => ( native, sint, linear, noaa, (1, 1), 16, all_flags, 4),
2218 Self::Rgba32Float => ( native, nearest, linear, noaa, (1, 1), 16, all_flags, 4),
2220 // Depth-stencil textures
2221 Self::Depth32Float => ( native, depth, linear, msaa, (1, 1), 4, attachment, 1),
2222 Self::Depth32FloatStencil8 =>( d32_s8, depth, linear, msaa, (1, 1), 4, attachment, 2),
2223 Self::Depth24Plus => ( native, depth, linear, msaa, (1, 1), 4, attachment, 1),
2224 Self::Depth24PlusStencil8 => ( native, depth, linear, msaa, (1, 1), 4, attachment, 2),
2225 Self::Depth24UnormStencil8 => ( d24_s8, depth, linear, msaa, (1, 1), 4, attachment, 2),
2227 // Packed uncompressed
2228 Self::Rgb9e5Ufloat => ( native, float, linear, noaa, (1, 1), 4, basic, 3),
2230 // Optional normalized 16-bit-per-channel formats
2231 Self::R16Unorm => (norm16bit, float, linear, msaa, (1, 1), 2, storage, 1),
2232 Self::R16Snorm => (norm16bit, float, linear, msaa, (1, 1), 2, storage, 1),
2233 Self::Rg16Unorm => (norm16bit, float, linear, msaa, (1, 1), 4, storage, 2),
2234 Self::Rg16Snorm => (norm16bit, float, linear, msaa, (1, 1), 4, storage, 2),
2235 Self::Rgba16Unorm => (norm16bit, float, linear, msaa, (1, 1), 8, storage, 4),
2236 Self::Rgba16Snorm => (norm16bit, float, linear, msaa, (1, 1), 8, storage, 4),
2238 // BCn compressed textures
2239 Self::Bc1RgbaUnorm => ( bc, float, linear, noaa, (4, 4), 8, basic, 4),
2240 Self::Bc1RgbaUnormSrgb => ( bc, float, corrected, noaa, (4, 4), 8, basic, 4),
2241 Self::Bc2RgbaUnorm => ( bc, float, linear, noaa, (4, 4), 16, basic, 4),
2242 Self::Bc2RgbaUnormSrgb => ( bc, float, corrected, noaa, (4, 4), 16, basic, 4),
2243 Self::Bc3RgbaUnorm => ( bc, float, linear, noaa, (4, 4), 16, basic, 4),
2244 Self::Bc3RgbaUnormSrgb => ( bc, float, corrected, noaa, (4, 4), 16, basic, 4),
2245 Self::Bc4RUnorm => ( bc, float, linear, noaa, (4, 4), 8, basic, 1),
2246 Self::Bc4RSnorm => ( bc, float, linear, noaa, (4, 4), 8, basic, 1),
2247 Self::Bc5RgUnorm => ( bc, float, linear, noaa, (4, 4), 16, basic, 2),
2248 Self::Bc5RgSnorm => ( bc, float, linear, noaa, (4, 4), 16, basic, 2),
2249 Self::Bc6hRgbUfloat => ( bc, float, linear, noaa, (4, 4), 16, basic, 3),
2250 Self::Bc6hRgbSfloat => ( bc, float, linear, noaa, (4, 4), 16, basic, 3),
2251 Self::Bc7RgbaUnorm => ( bc, float, linear, noaa, (4, 4), 16, basic, 4),
2252 Self::Bc7RgbaUnormSrgb => ( bc, float, corrected, noaa, (4, 4), 16, basic, 4),
2254 // ETC compressed textures
2255 Self::Etc2Rgb8Unorm => ( etc2, float, linear, noaa, (4, 4), 8, basic, 3),
2256 Self::Etc2Rgb8UnormSrgb => ( etc2, float, corrected, noaa, (4, 4), 8, basic, 3),
2257 Self::Etc2Rgb8A1Unorm => ( etc2, float, linear, noaa, (4, 4), 8, basic, 4),
2258 Self::Etc2Rgb8A1UnormSrgb => ( etc2, float, corrected, noaa, (4, 4), 8, basic, 4),
2259 Self::Etc2Rgba8Unorm => ( etc2, float, linear, noaa, (4, 4), 16, basic, 4),
2260 Self::Etc2Rgba8UnormSrgb => ( etc2, float, corrected, noaa, (4, 4), 16, basic, 4),
2261 Self::EacR11Unorm => ( etc2, float, linear, noaa, (4, 4), 8, basic, 1),
2262 Self::EacR11Snorm => ( etc2, float, linear, noaa, (4, 4), 8, basic, 1),
2263 Self::EacRg11Unorm => ( etc2, float, linear, noaa, (4, 4), 16, basic, 2),
2264 Self::EacRg11Snorm => ( etc2, float, linear, noaa, (4, 4), 16, basic, 2),
2266 // ASTC compressed textures
2267 Self::Astc { block, channel } => {
2268 let (feature, color_space) = match channel {
2269 AstcChannel::Hdr => (astc_hdr, linear),
2270 AstcChannel::Unorm => (astc_ldr, linear),
2271 AstcChannel::UnormSrgb => (astc_ldr, corrected),
2273 let dimensions = match block {
2274 AstcBlock::B4x4 => (4, 4),
2275 AstcBlock::B5x4 => (5, 4),
2276 AstcBlock::B5x5 => (5, 5),
2277 AstcBlock::B6x5 => (6, 5),
2278 AstcBlock::B6x6 => (6, 6),
2279 AstcBlock::B8x5 => (8, 5),
2280 AstcBlock::B8x6 => (8, 6),
2281 AstcBlock::B8x8 => (8, 8),
2282 AstcBlock::B10x5 => (10, 5),
2283 AstcBlock::B10x6 => (10, 6),
2284 AstcBlock::B10x8 => (10, 8),
2285 AstcBlock::B10x10 => (10, 10),
2286 AstcBlock::B12x10 => (12, 10),
2287 AstcBlock::B12x12 => (12, 12),
2289 (feature, float, color_space, noaa, dimensions, 16, basic, 4)
2293 let mut flags = msaa_flags;
2295 TextureFormatFeatureFlags::FILTERABLE,
2296 sample_type == TextureSampleType::Float { filterable: true },
2305 srgb: match color_space {
2306 ColorSpace::Linear => false,
2307 ColorSpace::Corrected => true,
2309 guaranteed_format_features: TextureFormatFeatures {
2317 bitflags::bitflags! {
2318 /// Color write mask. Disabled color channels will not be written to.
2320 /// Corresponds to [WebGPU `GPUColorWriteFlags`](
2321 /// https://gpuweb.github.io/gpuweb/#typedefdef-gpucolorwriteflags).
2322 #[repr(transparent)]
2323 pub struct ColorWrites: u32 {
2324 /// Enable red channel writes
2326 /// Enable green channel writes
2327 const GREEN = 1 << 1;
2328 /// Enable blue channel writes
2329 const BLUE = 1 << 2;
2330 /// Enable alpha channel writes
2331 const ALPHA = 1 << 3;
2332 /// Enable red, green, and blue channel writes
2333 const COLOR = Self::RED.bits | Self::GREEN.bits | Self::BLUE.bits;
2334 /// Enable writes to all channels.
2335 const ALL = Self::RED.bits | Self::GREEN.bits | Self::BLUE.bits | Self::ALPHA.bits;
2339 #[cfg(feature = "bitflags_serde_shim")]
2340 bitflags_serde_shim::impl_serde_for_bitflags!(ColorWrites);
2342 impl Default for ColorWrites {
2343 fn default() -> Self {
2348 /// Passed to `Device::poll` to control how and if it should block.
2350 pub enum Maintain<T> {
2351 /// On native backends, block until the given submission has
2352 /// completed execution, and any callbacks have been invoked.
2354 /// On the web, this has no effect. Callbacks are invoked from the
2355 /// window event loop.
2356 WaitForSubmissionIndex(T),
2357 /// Same as WaitForSubmissionIndex but waits for the most recent submission.
2359 /// Check the device for a single time without blocking.
2363 impl<T> Maintain<T> {
2364 /// This maintain represents a wait of some kind.
2365 pub fn is_wait(&self) -> bool {
2367 Self::WaitForSubmissionIndex(..) | Self::Wait => true,
2368 Self::Poll => false,
2372 /// Map on the wait index type.
2373 pub fn map_index<U, F>(self, func: F) -> Maintain<U>
2378 Self::WaitForSubmissionIndex(i) => Maintain::WaitForSubmissionIndex(func(i)),
2379 Self::Wait => Maintain::Wait,
2380 Self::Poll => Maintain::Poll,
2385 /// State of the stencil operation (fixed-pipeline stage).
2387 /// For use in [`DepthStencilState`].
2389 /// Corresponds to a portion of [WebGPU `GPUDepthStencilState`](
2390 /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
2392 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
2393 #[cfg_attr(feature = "trace", derive(Serialize))]
2394 #[cfg_attr(feature = "replay", derive(Deserialize))]
2395 pub struct StencilState {
2396 /// Front face mode.
2397 pub front: StencilFaceState,
2399 pub back: StencilFaceState,
2400 /// Stencil values are AND'd with this mask when reading and writing from the stencil buffer. Only low 8 bits are used.
2402 /// Stencil values are AND'd with this mask when writing to the stencil buffer. Only low 8 bits are used.
2403 pub write_mask: u32,
2407 /// Returns true if the stencil test is enabled.
2408 pub fn is_enabled(&self) -> bool {
2409 (self.front != StencilFaceState::IGNORE || self.back != StencilFaceState::IGNORE)
2410 && (self.read_mask != 0 || self.write_mask != 0)
2412 /// Returns true if the state doesn't mutate the target values.
2413 pub fn is_read_only(&self) -> bool {
2414 self.write_mask == 0
2416 /// Returns true if the stencil state uses the reference value for testing.
2417 pub fn needs_ref_value(&self) -> bool {
2418 self.front.needs_ref_value() || self.back.needs_ref_value()
2422 /// Describes the biasing setting for the depth target.
2424 /// For use in [`DepthStencilState`].
2426 /// Corresponds to a portion of [WebGPU `GPUDepthStencilState`](
2427 /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
2429 #[derive(Clone, Copy, Debug, Default, PartialEq)]
2430 #[cfg_attr(feature = "trace", derive(Serialize))]
2431 #[cfg_attr(feature = "replay", derive(Deserialize))]
2432 pub struct DepthBiasState {
2433 /// Constant depth biasing factor, in basic units of the depth format.
2435 /// Slope depth biasing factor.
2436 pub slope_scale: f32,
2437 /// Depth bias clamp value (absolute).
2441 impl DepthBiasState {
2442 /// Returns true if the depth biasing is enabled.
2443 pub fn is_enabled(&self) -> bool {
2444 self.constant != 0 || self.slope_scale != 0.0
2448 /// Describes the depth/stencil state in a render pipeline.
2450 /// Corresponds to [WebGPU `GPUDepthStencilState`](
2451 /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
2453 #[derive(Clone, Debug, PartialEq)]
2454 #[cfg_attr(feature = "trace", derive(Serialize))]
2455 #[cfg_attr(feature = "replay", derive(Deserialize))]
2456 pub struct DepthStencilState {
2457 /// Format of the depth/stencil buffer, must be special depth format. Must match the the format
2458 /// of the depth/stencil attachment in [`CommandEncoder::begin_render_pass`][CEbrp].
2460 /// [CEbrp]: ../wgpu/struct.CommandEncoder.html#method.begin_render_pass
2461 pub format: TextureFormat,
2462 /// If disabled, depth will not be written to.
2463 pub depth_write_enabled: bool,
2464 /// Comparison function used to compare depth values in the depth test.
2465 pub depth_compare: CompareFunction,
2467 #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
2468 pub stencil: StencilState,
2469 /// Depth bias state.
2470 #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
2471 pub bias: DepthBiasState,
2474 impl DepthStencilState {
2475 /// Returns true if the depth testing is enabled.
2476 pub fn is_depth_enabled(&self) -> bool {
2477 self.depth_compare != CompareFunction::Always || self.depth_write_enabled
2480 /// Returns true if the state doesn't mutate the depth buffer.
2481 pub fn is_depth_read_only(&self) -> bool {
2482 !self.depth_write_enabled
2485 /// Returns true if the state doesn't mutate the stencil.
2486 pub fn is_stencil_read_only(&self) -> bool {
2487 self.stencil.is_read_only()
2490 /// Returns true if the state doesn't mutate either depth or stencil of the target.
2491 pub fn is_read_only(&self) -> bool {
2492 self.is_depth_read_only() && self.is_stencil_read_only()
2496 /// Format of indices used with pipeline.
2498 /// Corresponds to [WebGPU `GPUIndexFormat`](
2499 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuindexformat).
2501 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2502 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
2503 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2504 pub enum IndexFormat {
2505 /// Indices are 16 bit unsigned integers.
2507 /// Indices are 32 bit unsigned integers.
2511 impl Default for IndexFormat {
2512 fn default() -> Self {
2517 /// Operation to perform on the stencil value.
2519 /// Corresponds to [WebGPU `GPUStencilOperation`](
2520 /// https://gpuweb.github.io/gpuweb/#enumdef-gpustenciloperation).
2522 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2523 #[cfg_attr(feature = "trace", derive(Serialize))]
2524 #[cfg_attr(feature = "replay", derive(Deserialize))]
2525 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2526 pub enum StencilOperation {
2527 /// Keep stencil value unchanged.
2529 /// Set stencil value to zero.
2531 /// Replace stencil value with value provided in most recent call to
2532 /// [`RenderPass::set_stencil_reference`][RPssr].
2534 /// [RPssr]: ../wgpu/struct.RenderPass.html#method.set_stencil_reference
2536 /// Bitwise inverts stencil value.
2538 /// Increments stencil value by one, clamping on overflow.
2540 /// Decrements stencil value by one, clamping on underflow.
2542 /// Increments stencil value by one, wrapping on overflow.
2544 /// Decrements stencil value by one, wrapping on underflow.
2548 impl Default for StencilOperation {
2549 fn default() -> Self {
2554 /// Describes stencil state in a render pipeline.
2556 /// If you are not using stencil state, set this to [`StencilFaceState::IGNORE`].
2558 /// Corresponds to [WebGPU `GPUStencilFaceState`](
2559 /// https://gpuweb.github.io/gpuweb/#dictdef-gpustencilfacestate).
2561 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2562 #[cfg_attr(feature = "trace", derive(Serialize))]
2563 #[cfg_attr(feature = "replay", derive(Deserialize))]
2564 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
2565 pub struct StencilFaceState {
2566 /// Comparison function that determines if the fail_op or pass_op is used on the stencil buffer.
2567 pub compare: CompareFunction,
2568 /// Operation that is preformed when stencil test fails.
2569 pub fail_op: StencilOperation,
2570 /// Operation that is performed when depth test fails but stencil test succeeds.
2571 pub depth_fail_op: StencilOperation,
2572 /// Operation that is performed when stencil test success.
2573 pub pass_op: StencilOperation,
2576 impl StencilFaceState {
2577 /// Ignore the stencil state for the face.
2578 pub const IGNORE: Self = StencilFaceState {
2579 compare: CompareFunction::Always,
2580 fail_op: StencilOperation::Keep,
2581 depth_fail_op: StencilOperation::Keep,
2582 pass_op: StencilOperation::Keep,
2585 /// Returns true if the face state uses the reference value for testing or operation.
2586 pub fn needs_ref_value(&self) -> bool {
2587 self.compare.needs_ref_value()
2588 || self.fail_op == StencilOperation::Replace
2589 || self.depth_fail_op == StencilOperation::Replace
2590 || self.pass_op == StencilOperation::Replace
2594 impl Default for StencilFaceState {
2595 fn default() -> Self {
2600 /// Comparison function used for depth and stencil operations.
2602 /// Corresponds to [WebGPU `GPUCompareFunction`](
2603 /// https://gpuweb.github.io/gpuweb/#enumdef-gpucomparefunction).
2605 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2606 #[cfg_attr(feature = "trace", derive(Serialize))]
2607 #[cfg_attr(feature = "replay", derive(Deserialize))]
2608 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2609 pub enum CompareFunction {
2610 /// Function never passes
2612 /// Function passes if new value less than existing value
2614 /// Function passes if new value is equal to existing value. When using
2615 /// this compare function, make sure to mark your Vertex Shader's `@builtin(position)`
2616 /// output as `@invariant` to prevent artifacting.
2618 /// Function passes if new value is less than or equal to existing value
2620 /// Function passes if new value is greater than existing value
2622 /// Function passes if new value is not equal to existing value. When using
2623 /// this compare function, make sure to mark your Vertex Shader's `@builtin(position)`
2624 /// output as `@invariant` to prevent artifacting.
2626 /// Function passes if new value is greater than or equal to existing value
2628 /// Function always passes
2632 impl CompareFunction {
2633 /// Returns true if the comparison depends on the reference value.
2634 pub fn needs_ref_value(self) -> bool {
2636 Self::Never | Self::Always => false,
2642 /// Whether a vertex buffer is indexed by vertex or by instance.
2644 /// Consider a call to [`RenderPass::draw`] like this:
2647 /// render_pass.draw(vertices, instances)
2650 /// where `vertices` is a `Range<u32>` of vertex indices, and
2651 /// `instances` is a `Range<u32>` of instance indices.
2653 /// For this call, `wgpu` invokes the vertex shader entry point once
2654 /// for every possible `(v, i)` pair, where `v` is drawn from
2655 /// `vertices` and `i` is drawn from `instances`. These invocations
2656 /// may happen in any order, and will usually run in parallel.
2658 /// Each vertex buffer has a step mode, established by the
2659 /// [`step_mode`] field of its [`VertexBufferLayout`], given when the
2660 /// pipeline was created. Buffers whose step mode is [`Vertex`] use
2661 /// `v` as the index into their contents, whereas buffers whose step
2662 /// mode is [`Instance`] use `i`. The indicated buffer element then
2663 /// contributes zero or more attribute values for the `(v, i)` vertex
2664 /// shader invocation to use, based on the [`VertexBufferLayout`]'s
2665 /// [`attributes`] list.
2667 /// You can visualize the results from all these vertex shader
2668 /// invocations as a matrix with a row for each `i` from `instances`,
2669 /// and with a column for each `v` from `vertices`. In one sense, `v`
2670 /// and `i` are symmetrical: both are used to index vertex buffers and
2671 /// provide attribute values. But the key difference between `v` and
2672 /// `i` is that line and triangle primitives are built from the values
2673 /// of each row, along which `i` is constant and `v` varies, not the
2676 /// An indexed draw call works similarly:
2679 /// render_pass.draw_indexed(indices, base_vertex, instances)
2682 /// The only difference is that `v` values are drawn from the contents
2683 /// of the index buffer—specifically, the subrange of the index
2684 /// buffer given by `indices`—instead of simply being sequential
2685 /// integers, as they are in a `draw` call.
2687 /// A non-instanced call, where `instances` is `0..1`, is simply a
2688 /// matrix with only one row.
2690 /// Corresponds to [WebGPU `GPUVertexStepMode`](
2691 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexstepmode).
2693 /// [`RenderPass::draw`]: ../wgpu/struct.RenderPass.html#method.draw
2694 /// [`VertexBufferLayout`]: ../wgpu/struct.VertexBufferLayout.html
2695 /// [`step_mode`]: ../wgpu/struct.VertexBufferLayout.html#structfield.step_mode
2696 /// [`attributes`]: ../wgpu/struct.VertexBufferLayout.html#structfield.attributes
2697 /// [`Vertex`]: VertexStepMode::Vertex
2698 /// [`Instance`]: VertexStepMode::Instance
2700 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2701 #[cfg_attr(feature = "trace", derive(Serialize))]
2702 #[cfg_attr(feature = "replay", derive(Deserialize))]
2703 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2704 pub enum VertexStepMode {
2705 /// Vertex data is advanced every vertex.
2707 /// Vertex data is advanced every instance.
2711 impl Default for VertexStepMode {
2712 fn default() -> Self {
2713 VertexStepMode::Vertex
2717 /// Vertex inputs (attributes) to shaders.
2719 /// Arrays of these can be made with the [`vertex_attr_array`]
2720 /// macro. Vertex attributes are assumed to be tightly packed.
2722 /// Corresponds to [WebGPU `GPUVertexAttribute`](
2723 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuvertexattribute).
2725 /// [`vertex_attr_array`]: ../wgpu/macro.vertex_attr_array.html
2727 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2728 #[cfg_attr(feature = "trace", derive(Serialize))]
2729 #[cfg_attr(feature = "replay", derive(Deserialize))]
2730 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
2731 pub struct VertexAttribute {
2732 /// Format of the input
2733 pub format: VertexFormat,
2734 /// Byte offset of the start of the input
2735 pub offset: BufferAddress,
2736 /// Location for this input. Must match the location in the shader.
2737 pub shader_location: ShaderLocation,
2740 /// Vertex Format for a [`VertexAttribute`] (input).
2742 /// Corresponds to [WebGPU `GPUVertexFormat`](
2743 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexformat).
2745 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2746 #[cfg_attr(feature = "trace", derive(Serialize))]
2747 #[cfg_attr(feature = "replay", derive(Deserialize))]
2748 #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
2749 pub enum VertexFormat {
2750 /// Two unsigned bytes (u8). `uvec2` in shaders.
2752 /// Four unsigned bytes (u8). `uvec4` in shaders.
2754 /// Two signed bytes (i8). `ivec2` in shaders.
2756 /// Four signed bytes (i8). `ivec4` in shaders.
2758 /// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2` in shaders.
2760 /// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4` in shaders.
2762 /// Two signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec2` in shaders.
2764 /// Four signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec4` in shaders.
2766 /// Two unsigned shorts (u16). `uvec2` in shaders.
2768 /// Four unsigned shorts (u16). `uvec4` in shaders.
2770 /// Two signed shorts (i16). `ivec2` in shaders.
2772 /// Four signed shorts (i16). `ivec4` in shaders.
2774 /// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2` in shaders.
2776 /// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4` in shaders.
2778 /// Two signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec2` in shaders.
2780 /// Four signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec4` in shaders.
2782 /// Two half-precision floats (no Rust equiv). `vec2` in shaders.
2784 /// Four half-precision floats (no Rust equiv). `vec4` in shaders.
2786 /// One single-precision float (f32). `float` in shaders.
2788 /// Two single-precision floats (f32). `vec2` in shaders.
2790 /// Three single-precision floats (f32). `vec3` in shaders.
2792 /// Four single-precision floats (f32). `vec4` in shaders.
2794 /// One unsigned int (u32). `uint` in shaders.
2796 /// Two unsigned ints (u32). `uvec2` in shaders.
2798 /// Three unsigned ints (u32). `uvec3` in shaders.
2800 /// Four unsigned ints (u32). `uvec4` in shaders.
2802 /// One signed int (i32). `int` in shaders.
2804 /// Two signed ints (i32). `ivec2` in shaders.
2806 /// Three signed ints (i32). `ivec3` in shaders.
2808 /// Four signed ints (i32). `ivec4` in shaders.
2810 /// One double-precision float (f64). `double` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2812 /// Two double-precision floats (f64). `dvec2` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2814 /// Three double-precision floats (f64). `dvec3` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2816 /// Four double-precision floats (f64). `dvec4` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2821 /// Returns the byte size of the format.
2822 pub const fn size(&self) -> u64 {
2824 Self::Uint8x2 | Self::Sint8x2 | Self::Unorm8x2 | Self::Snorm8x2 => 2,
2836 | Self::Sint32 => 4,
2845 | Self::Float64 => 8,
2846 Self::Float32x3 | Self::Uint32x3 | Self::Sint32x3 => 12,
2847 Self::Float32x4 | Self::Uint32x4 | Self::Sint32x4 | Self::Float64x2 => 16,
2848 Self::Float64x3 => 24,
2849 Self::Float64x4 => 32,
2854 bitflags::bitflags! {
2855 /// Different ways that you can use a buffer.
2857 /// The usages determine what kind of memory the buffer is allocated from and what
2858 /// actions the buffer can partake in.
2860 /// Corresponds to [WebGPU `GPUBufferUsageFlags`](
2861 /// https://gpuweb.github.io/gpuweb/#typedefdef-gpubufferusageflags).
2862 #[repr(transparent)]
2863 pub struct BufferUsages: u32 {
2864 /// Allow a buffer to be mapped for reading using [`Buffer::map_async`] + [`Buffer::get_mapped_range`].
2865 /// This does not include creating a buffer with [`BufferDescriptor::mapped_at_creation`] set.
2867 /// If [`Features::MAPPABLE_PRIMARY_BUFFERS`] isn't enabled, the only other usage a buffer
2868 /// may have is COPY_DST.
2869 const MAP_READ = 1 << 0;
2870 /// Allow a buffer to be mapped for writing using [`Buffer::map_async`] + [`Buffer::get_mapped_range_mut`].
2871 /// This does not include creating a buffer with `mapped_at_creation` set.
2873 /// If [`Features::MAPPABLE_PRIMARY_BUFFERS`] feature isn't enabled, the only other usage a buffer
2874 /// may have is COPY_SRC.
2875 const MAP_WRITE = 1 << 1;
2876 /// Allow a buffer to be the source buffer for a [`CommandEncoder::copy_buffer_to_buffer`] or [`CommandEncoder::copy_buffer_to_texture`]
2878 const COPY_SRC = 1 << 2;
2879 /// Allow a buffer to be the destination buffer for a [`CommandEncoder::copy_buffer_to_buffer`], [`CommandEncoder::copy_texture_to_buffer`],
2880 /// [`CommandEncoder::clear_buffer`] or [`Queue::write_buffer`] operation.
2881 const COPY_DST = 1 << 3;
2882 /// Allow a buffer to be the index buffer in a draw operation.
2883 const INDEX = 1 << 4;
2884 /// Allow a buffer to be the vertex buffer in a draw operation.
2885 const VERTEX = 1 << 5;
2886 /// Allow a buffer to be a [`BufferBindingType::Uniform`] inside a bind group.
2887 const UNIFORM = 1 << 6;
2888 /// Allow a buffer to be a [`BufferBindingType::Storage`] inside a bind group.
2889 const STORAGE = 1 << 7;
2890 /// Allow a buffer to be the indirect buffer in an indirect draw call.
2891 const INDIRECT = 1 << 8;
2895 #[cfg(feature = "bitflags_serde_shim")]
2896 bitflags_serde_shim::impl_serde_for_bitflags!(BufferUsages);
2898 /// Describes a [`Buffer`](../wgpu/struct.Buffer.html).
2900 /// Corresponds to [WebGPU `GPUBufferDescriptor`](
2901 /// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferdescriptor).
2903 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
2904 #[cfg_attr(feature = "trace", derive(Serialize))]
2905 #[cfg_attr(feature = "replay", derive(Deserialize))]
2906 pub struct BufferDescriptor<L> {
2907 /// Debug label of a buffer. This will show up in graphics debuggers for easy identification.
2909 /// Size of a buffer.
2910 pub size: BufferAddress,
2911 /// Usages of a buffer. If the buffer is used in any way that isn't specified here, the operation
2913 pub usage: BufferUsages,
2914 /// Allows a buffer to be mapped immediately after they are made. It does not have to be [`BufferUsages::MAP_READ`] or
2915 /// [`BufferUsages::MAP_WRITE`], all buffers are allowed to be mapped at creation.
2916 pub mapped_at_creation: bool,
2919 impl<L> BufferDescriptor<L> {
2921 pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> BufferDescriptor<K> {
2923 label: fun(&self.label),
2926 mapped_at_creation: self.mapped_at_creation,
2931 /// Describes a [`CommandEncoder`](../wgpu/struct.CommandEncoder.html).
2933 /// Corresponds to [WebGPU `GPUCommandEncoderDescriptor`](
2934 /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandencoderdescriptor).
2936 #[cfg_attr(feature = "trace", derive(Serialize))]
2937 #[cfg_attr(feature = "replay", derive(Deserialize))]
2938 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
2939 pub struct CommandEncoderDescriptor<L> {
2940 /// Debug label for the command encoder. This will show up in graphics debuggers for easy identification.
2944 impl<L> CommandEncoderDescriptor<L> {
2946 pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandEncoderDescriptor<K> {
2947 CommandEncoderDescriptor {
2948 label: fun(&self.label),
2953 impl<T> Default for CommandEncoderDescriptor<Option<T>> {
2954 fn default() -> Self {
2955 Self { label: None }
2959 /// Behavior of the presentation engine based on frame rate.
2961 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
2962 #[cfg_attr(feature = "trace", derive(Serialize))]
2963 #[cfg_attr(feature = "replay", derive(Deserialize))]
2964 pub enum PresentMode {
2965 /// Chooses FifoRelaxed -> Fifo based on availability.
2967 /// Because of the fallback behavior, it is supported everywhere.
2969 /// Chooses Immediate -> Mailbox -> Fifo (on web) based on availability.
2971 /// Because of the fallback behavior, it is supported everywhere.
2973 /// Presentation frames are kept in a First-In-First-Out queue approximately 3 frames
2974 /// long. Every vertical blanking period, the presentation engine will pop a frame
2975 /// off the queue to display. If there is no frame to display, it will present the same
2976 /// frame again until the next vblank.
2978 /// When a present command is executed on the gpu, the presented image is added on the queue.
2980 /// No tearing will be observed.
2982 /// Calls to get_current_texture will block until there is a spot in the queue.
2984 /// Supported on all platforms.
2986 /// If you don't know what mode to choose, choose this mode. This is traditionally called "Vsync On".
2988 /// Presentation frames are kept in a First-In-First-Out queue approximately 3 frames
2989 /// long. Every vertical blanking period, the presentation engine will pop a frame
2990 /// off the queue to display. If there is no frame to display, it will present the
2991 /// same frame until there is a frame in the queue. The moment there is a frame in the
2992 /// queue, it will immediately pop the frame off the queue.
2994 /// When a present command is executed on the gpu, the presented image is added on the queue.
2996 /// Tearing will be observed if frames last more than one vblank as the front buffer.
2998 /// Calls to get_current_texture will block until there is a spot in the queue.
3000 /// Supported on AMD on Vulkan.
3002 /// This is traditionally called "Adaptive Vsync"
3004 /// Presentation frames are not queued at all. The moment a present command
3005 /// is executed on the GPU, the presented image is swapped onto the front buffer
3008 /// Tearing can be observed.
3010 /// Supported on most platforms except older DX12 and Wayland.
3012 /// This is traditionally called "Vsync Off".
3014 /// Presentation frames are kept in a single-frame queue. Every vertical blanking period,
3015 /// the presentation engine will pop a frame from the queue. If there is no frame to display,
3016 /// it will present the same frame again until the next vblank.
3018 /// When a present command is executed on the gpu, the frame will be put into the queue.
3019 /// If there was already a frame in the queue, the new frame will _replace_ the old frame
3022 /// No tearing will be observed.
3024 /// Supported on DX11/12 on Windows 10, NVidia on Vulkan and Wayland on Vulkan.
3026 /// This is traditionally called "Fast Vsync"
3030 impl Default for PresentMode {
3031 fn default() -> Self {
3036 bitflags::bitflags! {
3037 /// Different ways that you can use a texture.
3039 /// The usages determine what kind of memory the texture is allocated from and what
3040 /// actions the texture can partake in.
3042 /// Corresponds to [WebGPU `GPUTextureUsageFlags`](
3043 /// https://gpuweb.github.io/gpuweb/#typedefdef-gputextureusageflags).
3044 #[repr(transparent)]
3045 pub struct TextureUsages: u32 {
3046 /// Allows a texture to be the source in a [`CommandEncoder::copy_texture_to_buffer`] or
3047 /// [`CommandEncoder::copy_texture_to_texture`] operation.
3048 const COPY_SRC = 1 << 0;
3049 /// Allows a texture to be the destination in a [`CommandEncoder::copy_buffer_to_texture`],
3050 /// [`CommandEncoder::copy_texture_to_texture`], or [`Queue::write_texture`] operation.
3051 const COPY_DST = 1 << 1;
3052 /// Allows a texture to be a [`BindingType::Texture`] in a bind group.
3053 const TEXTURE_BINDING = 1 << 2;
3054 /// Allows a texture to be a [`BindingType::StorageTexture`] in a bind group.
3055 const STORAGE_BINDING = 1 << 3;
3056 /// Allows a texture to be an output attachment of a renderpass.
3057 const RENDER_ATTACHMENT = 1 << 4;
3061 #[cfg(feature = "bitflags_serde_shim")]
3062 bitflags_serde_shim::impl_serde_for_bitflags!(TextureUsages);
3064 /// Configures a [`Surface`] for presentation.
3066 /// [`Surface`]: ../wgpu/struct.Surface.html
3068 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3069 #[cfg_attr(feature = "trace", derive(Serialize))]
3070 #[cfg_attr(feature = "replay", derive(Deserialize))]
3071 pub struct SurfaceConfiguration {
3072 /// The usage of the swap chain. The only supported usage is `RENDER_ATTACHMENT`.
3073 pub usage: TextureUsages,
3074 /// The texture format of the swap chain. The only formats that are guaranteed are
3075 /// `Bgra8Unorm` and `Bgra8UnormSrgb`
3076 pub format: TextureFormat,
3077 /// Width of the swap chain. Must be the same size as the surface.
3079 /// Height of the swap chain. Must be the same size as the surface.
3081 /// Presentation mode of the swap chain. Fifo is the only mode guaranteed to be supported.
3082 /// FifoRelaxed, Immediate, and Mailbox will crash if unsupported, while AutoVsync and
3083 /// AutoNoVsync will gracefully do a designed sets of fallbacks if their primary modes are
3085 pub present_mode: PresentMode,
3088 /// Status of the recieved surface image.
3091 pub enum SurfaceStatus {
3094 /// The swap chain is operational, but it does no longer perfectly
3095 /// match the surface. A re-configuration is needed.
3097 /// Unable to get the next frame, timed out.
3099 /// The surface under the swap chain has changed.
3101 /// The surface under the swap chain is lost.
3105 /// RGBA double precision color.
3107 /// This is not to be used as a generic color type, only for specific wgpu interfaces.
3109 #[derive(Clone, Copy, Debug, Default, PartialEq)]
3110 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3111 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
3123 #[allow(missing_docs)]
3125 pub const TRANSPARENT: Self = Self {
3131 pub const BLACK: Self = Self {
3137 pub const WHITE: Self = Self {
3143 pub const RED: Self = Self {
3149 pub const GREEN: Self = Self {
3155 pub const BLUE: Self = Self {
3163 /// Dimensionality of a texture.
3165 /// Corresponds to [WebGPU `GPUTextureDimension`](
3166 /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturedimension).
3168 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3169 #[cfg_attr(feature = "trace", derive(Serialize))]
3170 #[cfg_attr(feature = "replay", derive(Deserialize))]
3171 pub enum TextureDimension {
3173 #[cfg_attr(feature = "serde", serde(rename = "1d"))]
3176 #[cfg_attr(feature = "serde", serde(rename = "2d"))]
3179 #[cfg_attr(feature = "serde", serde(rename = "3d"))]
3183 /// Origin of a copy to/from a texture.
3185 /// Corresponds to [WebGPU `GPUOrigin3D`](
3186 /// https://gpuweb.github.io/gpuweb/#typedefdef-gpuorigin3d).
3188 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3189 #[cfg_attr(feature = "trace", derive(Serialize))]
3190 #[cfg_attr(feature = "replay", derive(Deserialize))]
3191 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
3192 pub struct Origin3d {
3203 pub const ZERO: Self = Self { x: 0, y: 0, z: 0 };
3206 impl Default for Origin3d {
3207 fn default() -> Self {
3212 /// Extent of a texture related operation.
3214 /// Corresponds to [WebGPU `GPUExtent3D`](
3215 /// https://gpuweb.github.io/gpuweb/#typedefdef-gpuextent3d).
3217 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3218 #[cfg_attr(feature = "trace", derive(Serialize))]
3219 #[cfg_attr(feature = "replay", derive(Deserialize))]
3220 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
3221 pub struct Extent3d {
3227 #[cfg_attr(feature = "serde", serde(default = "default_depth"))]
3228 pub depth_or_array_layers: u32,
3231 #[cfg(feature = "serde")]
3232 fn default_depth() -> u32 {
3236 impl Default for Extent3d {
3237 fn default() -> Self {
3241 depth_or_array_layers: 1,
3247 /// Calculates the [physical size] backing a texture of the given
3248 /// format and extent. This includes padding to the block width
3249 /// and height of the format.
3251 /// This is the texture extent that you must upload at when uploading to _mipmaps_ of compressed textures.
3253 /// [physical size]: https://gpuweb.github.io/gpuweb/#physical-miplevel-specific-texture-extent
3254 pub fn physical_size(&self, format: TextureFormat) -> Self {
3255 let (block_width, block_height) = format.describe().block_dimensions;
3256 let block_width = block_width as u32;
3257 let block_height = block_height as u32;
3259 let width = ((self.width + block_width - 1) / block_width) * block_width;
3260 let height = ((self.height + block_height - 1) / block_height) * block_height;
3265 depth_or_array_layers: self.depth_or_array_layers,
3269 /// Calculates the maximum possible count of mipmaps.
3271 /// Treats the depth as part of the mipmaps. If calculating
3272 /// for a 2DArray texture, which does not mipmap depth, set depth to 1.
3273 pub fn max_mips(&self, dim: TextureDimension) -> u32 {
3275 TextureDimension::D1 => 1,
3276 TextureDimension::D2 => {
3277 let max_dim = self.width.max(self.height);
3278 32 - max_dim.leading_zeros()
3280 TextureDimension::D3 => {
3281 let max_dim = self.width.max(self.height.max(self.depth_or_array_layers));
3282 32 - max_dim.leading_zeros()
3287 /// Calculates the extent at a given mip level.
3288 /// Does *not* account for memory size being a multiple of block size.
3289 pub fn mip_level_size(&self, level: u32, is_3d_texture: bool) -> Extent3d {
3291 width: u32::max(1, self.width >> level),
3292 height: u32::max(1, self.height >> level),
3293 depth_or_array_layers: match is_3d_texture {
3294 false => self.depth_or_array_layers,
3295 true => u32::max(1, self.depth_or_array_layers >> level),
3302 fn test_physical_size() {
3303 let format = TextureFormat::Bc1RgbaUnormSrgb; // 4x4 blocks
3308 depth_or_array_layers: 1
3310 .physical_size(format),
3314 depth_or_array_layers: 1
3317 // Doesn't change, already aligned
3322 depth_or_array_layers: 1
3324 .physical_size(format),
3328 depth_or_array_layers: 1
3331 let format = TextureFormat::Astc {
3332 block: AstcBlock::B8x5,
3333 channel: AstcChannel::Unorm,
3339 depth_or_array_layers: 1
3341 .physical_size(format),
3345 depth_or_array_layers: 1
3351 fn test_max_mips() {
3357 depth_or_array_layers: 1
3359 .max_mips(TextureDimension::D1),
3367 depth_or_array_layers: 1
3369 .max_mips(TextureDimension::D2),
3376 depth_or_array_layers: 1
3378 .max_mips(TextureDimension::D2),
3385 depth_or_array_layers: 1000
3387 .max_mips(TextureDimension::D2),
3395 depth_or_array_layers: 60
3397 .max_mips(TextureDimension::D3),
3402 /// Describes a [`Texture`](../wgpu/struct.Texture.html).
3404 /// Corresponds to [WebGPU `GPUTextureDescriptor`](
3405 /// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor).
3407 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3408 #[cfg_attr(feature = "trace", derive(Serialize))]
3409 #[cfg_attr(feature = "replay", derive(Deserialize))]
3410 pub struct TextureDescriptor<L> {
3411 /// Debug label of the texture. This will show up in graphics debuggers for easy identification.
3413 /// Size of the texture. All components must be greater than zero. For a
3414 /// regular 1D/2D texture, the unused sizes will be 1. For 2DArray textures,
3415 /// Z is the number of 2D textures in that array.
3417 /// Mip count of texture. For a texture with no extra mips, this must be 1.
3418 pub mip_level_count: u32,
3419 /// Sample count of texture. If this is not 1, texture must have [`BindingType::Texture::multisampled`] set to true.
3420 pub sample_count: u32,
3421 /// Dimensions of the texture.
3422 pub dimension: TextureDimension,
3423 /// Format of the texture.
3424 pub format: TextureFormat,
3425 /// Allowed usages of the texture. If used in other ways, the operation will panic.
3426 pub usage: TextureUsages,
3427 // TODO: missing view_formats https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-viewformats
3430 impl<L> TextureDescriptor<L> {
3432 pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor<K> {
3434 label: fun(&self.label),
3436 mip_level_count: self.mip_level_count,
3437 sample_count: self.sample_count,
3438 dimension: self.dimension,
3439 format: self.format,
3444 /// Calculates the extent at a given mip level.
3446 /// If the given mip level is larger than possible, returns None.
3448 /// Treats the depth as part of the mipmaps. If calculating
3449 /// for a 2DArray texture, which does not mipmap depth, set depth to 1.
3452 /// # use wgpu_types as wgpu;
3453 /// let desc = wgpu::TextureDescriptor {
3455 /// size: wgpu::Extent3d { width: 100, height: 60, depth_or_array_layers: 1 },
3456 /// mip_level_count: 7,
3457 /// sample_count: 1,
3458 /// dimension: wgpu::TextureDimension::D3,
3459 /// format: wgpu::TextureFormat::Rgba8Sint,
3460 /// usage: wgpu::TextureUsages::empty(),
3463 /// assert_eq!(desc.mip_level_size(0), Some(wgpu::Extent3d { width: 100, height: 60, depth_or_array_layers: 1 }));
3464 /// assert_eq!(desc.mip_level_size(1), Some(wgpu::Extent3d { width: 50, height: 30, depth_or_array_layers: 1 }));
3465 /// assert_eq!(desc.mip_level_size(2), Some(wgpu::Extent3d { width: 25, height: 15, depth_or_array_layers: 1 }));
3466 /// assert_eq!(desc.mip_level_size(3), Some(wgpu::Extent3d { width: 12, height: 7, depth_or_array_layers: 1 }));
3467 /// assert_eq!(desc.mip_level_size(4), Some(wgpu::Extent3d { width: 6, height: 3, depth_or_array_layers: 1 }));
3468 /// assert_eq!(desc.mip_level_size(5), Some(wgpu::Extent3d { width: 3, height: 1, depth_or_array_layers: 1 }));
3469 /// assert_eq!(desc.mip_level_size(6), Some(wgpu::Extent3d { width: 1, height: 1, depth_or_array_layers: 1 }));
3470 /// assert_eq!(desc.mip_level_size(7), None);
3472 pub fn mip_level_size(&self, level: u32) -> Option<Extent3d> {
3473 if level >= self.mip_level_count {
3479 .mip_level_size(level, self.dimension == TextureDimension::D3),
3483 /// Returns the number of array layers.
3484 pub fn array_layer_count(&self) -> u32 {
3485 match self.dimension {
3486 TextureDimension::D1 | TextureDimension::D3 => 1,
3487 TextureDimension::D2 => self.size.depth_or_array_layers,
3492 /// Kind of data the texture holds.
3494 /// Corresponds to [WebGPU `GPUTextureAspect`](
3495 /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureaspect).
3497 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3498 #[cfg_attr(feature = "trace", derive(Serialize))]
3499 #[cfg_attr(feature = "replay", derive(Deserialize))]
3500 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3501 pub enum TextureAspect {
3502 /// Depth, Stencil, and Color.
3510 impl Default for TextureAspect {
3511 fn default() -> Self {
3516 /// How edges should be handled in texture addressing.
3518 /// Corresponds to [WebGPU `GPUAddressMode`](
3519 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuaddressmode).
3521 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3522 #[cfg_attr(feature = "trace", derive(Serialize))]
3523 #[cfg_attr(feature = "replay", derive(Deserialize))]
3524 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3525 pub enum AddressMode {
3526 /// Clamp the value to the edge of the texture
3531 /// Repeat the texture in a tiling fashion
3536 /// Repeat the texture, mirroring it every repeat
3541 /// Clamp the value to the border of the texture
3542 /// Requires feature [`Features::ADDRESS_MODE_CLAMP_TO_BORDER`]
3549 impl Default for AddressMode {
3550 fn default() -> Self {
3555 /// Texel mixing mode when sampling between texels.
3557 /// Corresponds to [WebGPU `GPUFilterMode`](
3558 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufiltermode).
3560 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3561 #[cfg_attr(feature = "trace", derive(Serialize))]
3562 #[cfg_attr(feature = "replay", derive(Deserialize))]
3563 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3564 pub enum FilterMode {
3565 /// Nearest neighbor sampling.
3567 /// This creates a pixelated effect when used as a mag filter
3569 /// Linear Interpolation
3571 /// This makes textures smooth but blurry when used as a mag filter.
3575 impl Default for FilterMode {
3576 fn default() -> Self {
3581 /// A range of push constant memory to pass to a shader stage.
3582 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3583 #[cfg_attr(feature = "trace", derive(Serialize))]
3584 #[cfg_attr(feature = "replay", derive(Deserialize))]
3585 pub struct PushConstantRange {
3586 /// Stage push constant range is visible from. Each stage can only be served by at most one range.
3587 /// One range can serve multiple stages however.
3588 pub stages: ShaderStages,
3589 /// Range in push constant memory to use for the stage. Must be less than [`Limits::max_push_constant_size`].
3590 /// Start and end must be aligned to the 4s.
3591 pub range: Range<u32>,
3594 /// Describes a [`CommandBuffer`](../wgpu/struct.CommandBuffer.html).
3596 /// Corresponds to [WebGPU `GPUCommandBufferDescriptor`](
3597 /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandbufferdescriptor).
3599 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
3600 #[cfg_attr(feature = "trace", derive(Serialize))]
3601 #[cfg_attr(feature = "replay", derive(Deserialize))]
3602 pub struct CommandBufferDescriptor<L> {
3603 /// Debug label of this command buffer.
3607 impl<L> CommandBufferDescriptor<L> {
3609 pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandBufferDescriptor<K> {
3610 CommandBufferDescriptor {
3611 label: fun(&self.label),
3616 /// Describes the depth/stencil attachment for render bundles.
3618 /// Corresponds to a portion of [WebGPU `GPURenderBundleEncoderDescriptor`](
3619 /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundleencoderdescriptor).
3621 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3622 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
3623 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
3624 pub struct RenderBundleDepthStencil {
3625 /// Format of the attachment.
3626 pub format: TextureFormat,
3627 /// True if the depth aspect is used but not modified.
3628 pub depth_read_only: bool,
3629 /// True if the stencil aspect is used but not modified.
3630 pub stencil_read_only: bool,
3633 /// Describes a [`RenderBundle`](../wgpu/struct.RenderBundle.html).
3635 /// Corresponds to [WebGPU `GPURenderBundleDescriptor`](
3636 /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundledescriptor).
3638 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3639 #[cfg_attr(feature = "trace", derive(Serialize))]
3640 #[cfg_attr(feature = "replay", derive(Deserialize))]
3641 pub struct RenderBundleDescriptor<L> {
3642 /// Debug label of the render bundle encoder. This will show up in graphics debuggers for easy identification.
3646 impl<L> RenderBundleDescriptor<L> {
3648 pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> RenderBundleDescriptor<K> {
3649 RenderBundleDescriptor {
3650 label: fun(&self.label),
3655 impl<T> Default for RenderBundleDescriptor<Option<T>> {
3656 fn default() -> Self {
3657 Self { label: None }
3661 /// Layout of a texture in a buffer's memory.
3663 /// The bytes per row and rows per image can be hard to figure out so here are some examples:
3665 /// | Resolution | Format | Bytes per block | Pixels per block | Bytes per row | Rows per image |
3666 /// |------------|--------|-----------------|------------------|----------------------------------------|------------------------------|
3667 /// | 256x256 | RGBA8 | 4 | 1 * 1 * 1 | 256 * 4 = Some(1024) | None |
3668 /// | 32x16x8 | RGBA8 | 4 | 1 * 1 * 1 | 32 * 4 = 128 padded to 256 = Some(256) | None |
3669 /// | 256x256 | BC3 | 16 | 4 * 4 * 1 | 16 * (256 / 4) = 1024 = Some(1024) | None |
3670 /// | 64x64x8 | BC3 | 16 | 4 * 4 * 1 | 16 * (64 / 4) = 256 = Some(256) | 64 / 4 = 16 = Some(16) |
3672 /// Corresponds to [WebGPU `GPUImageDataLayout`](
3673 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagedatalayout).
3675 #[derive(Clone, Copy, Debug, Default)]
3676 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
3677 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
3678 pub struct ImageDataLayout {
3679 /// Offset into the buffer that is the start of the texture. Must be a multiple of texture block size.
3680 /// For non-compressed textures, this is 1.
3681 pub offset: BufferAddress,
3682 /// Bytes per "row" in an image.
3684 /// A row is one row of pixels or of compressed blocks in the x direction.
3686 /// This value is required if there are multiple rows (i.e. height or depth is more than one pixel or pixel block for compressed textures)
3688 /// Must be a multiple of 256 for [`CommandEncoder::copy_buffer_to_texture`][CEcbtt]
3689 /// and [`CommandEncoder::copy_texture_to_buffer`][CEcttb]. You must manually pad the
3690 /// image such that this is a multiple of 256. It will not affect the image data.
3692 /// [`Queue::write_texture`][Qwt] does not have this requirement.
3694 /// Must be a multiple of the texture block size. For non-compressed textures, this is 1.
3696 /// [CEcbtt]: ../wgpu/struct.CommandEncoder.html#method.copy_buffer_to_texture
3697 /// [CEcttb]: ../wgpu/struct.CommandEncoder.html#method.copy_texture_to_buffer
3698 /// [Qwt]: ../wgpu/struct.Queue.html#method.write_texture
3699 pub bytes_per_row: Option<NonZeroU32>,
3700 /// "Rows" that make up a single "image".
3702 /// A row is one row of pixels or of compressed blocks in the x direction.
3704 /// An image is one layer in the z direction of a 3D image or 2DArray texture.
3706 /// The amount of rows per image may be larger than the actual amount of rows of data.
3708 /// Required if there are multiple images (i.e. the depth is more than one).
3709 pub rows_per_image: Option<NonZeroU32>,
3712 /// Specific type of a buffer binding.
3714 /// Corresponds to [WebGPU `GPUBufferBindingType`](
3715 /// https://gpuweb.github.io/gpuweb/#enumdef-gpubufferbindingtype).
3716 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3717 #[cfg_attr(feature = "trace", derive(Serialize))]
3718 #[cfg_attr(feature = "replay", derive(Deserialize))]
3719 pub enum BufferBindingType {
3720 /// A buffer for uniform values.
3722 /// Example WGSL syntax:
3724 /// struct Globals {
3725 /// a_uniform: vec2<f32>,
3726 /// another_uniform: vec2<f32>,
3728 /// @group(0) @binding(0)
3729 /// var<uniform> globals: Globals;
3732 /// Example GLSL syntax:
3734 /// layout(std140, binding = 0)
3735 /// uniform Globals {
3737 /// vec2 anotherUniform;
3741 /// A storage buffer.
3743 /// Example WGSL syntax:
3745 /// @group(0) @binding(0)
3746 /// var<storage, read_write> my_element: array<vec4<f32>>;
3749 /// Example GLSL syntax:
3751 /// layout (set=0, binding=0) buffer myStorageBuffer {
3752 /// vec4 myElement[];
3756 /// If `true`, the buffer can only be read in the shader,
3758 /// - may or may not be annotated with `read` (WGSL).
3759 /// - must be annotated with `readonly` (GLSL).
3761 /// Example WGSL syntax:
3763 /// @group(0) @binding(0)
3764 /// var<storage, read> my_element: array<vec4<f32>>;
3767 /// Example GLSL syntax:
3769 /// layout (set=0, binding=0) readonly buffer myStorageBuffer {
3770 /// vec4 myElement[];
3777 impl Default for BufferBindingType {
3778 fn default() -> Self {
3783 /// Specific type of a sample in a texture binding.
3785 /// Corresponds to [WebGPU `GPUTextureSampleType`](
3786 /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturesampletype).
3787 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3788 #[cfg_attr(feature = "trace", derive(Serialize))]
3789 #[cfg_attr(feature = "replay", derive(Deserialize))]
3790 pub enum TextureSampleType {
3791 /// Sampling returns floats.
3793 /// Example WGSL syntax:
3795 /// @group(0) @binding(0)
3796 /// var t: texure_2d<f32>;
3799 /// Example GLSL syntax:
3801 /// layout(binding = 0)
3802 /// uniform texture2D t;
3805 /// If `filterable` is false, the texture can't be sampled with
3806 /// a filtering sampler.
3809 /// Sampling does the depth reference comparison.
3811 /// Example WGSL syntax:
3813 /// @group(0) @binding(0)
3814 /// var t: texture_depth_2d;
3817 /// Example GLSL syntax:
3819 /// layout(binding = 0)
3820 /// uniform texture2DShadow t;
3823 /// Sampling returns signed integers.
3825 /// Example WGSL syntax:
3827 /// @group(0) @binding(0)
3828 /// var t: texture_2d<i32>;
3831 /// Example GLSL syntax:
3833 /// layout(binding = 0)
3834 /// uniform itexture2D t;
3837 /// Sampling returns unsigned integers.
3839 /// Example WGSL syntax:
3841 /// @group(0) @binding(0)
3842 /// var t: texture_2d<u32>;
3845 /// Example GLSL syntax:
3847 /// layout(binding = 0)
3848 /// uniform utexture2D t;
3853 impl Default for TextureSampleType {
3854 fn default() -> Self {
3855 Self::Float { filterable: true }
3859 /// Specific type of a sample in a texture binding.
3861 /// For use in [`BindingType::StorageTexture`].
3863 /// Corresponds to [WebGPU `GPUStorageTextureAccess`](
3864 /// https://gpuweb.github.io/gpuweb/#enumdef-gpustoragetextureaccess).
3865 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3866 #[cfg_attr(feature = "trace", derive(Serialize))]
3867 #[cfg_attr(feature = "replay", derive(Deserialize))]
3868 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3869 pub enum StorageTextureAccess {
3870 /// The texture can only be written in the shader and it:
3871 /// - may or may not be annotated with `write` (WGSL).
3872 /// - must be annotated with `writeonly` (GLSL).
3874 /// Example WGSL syntax:
3876 /// @group(0) @binding(0)
3877 /// var my_storage_image: texture_storage_2d<f32, write>;
3880 /// Example GLSL syntax:
3882 /// layout(set=0, binding=0, r32f) writeonly uniform image2D myStorageImage;
3885 /// The texture can only be read in the shader and it must be annotated with `read` (WGSL) or
3886 /// `readonly` (GLSL).
3888 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] must be enabled to use this access
3889 /// mode. This is a native-only extension.
3891 /// Example WGSL syntax:
3893 /// @group(0) @binding(0)
3894 /// var my_storage_image: texture_storage_2d<f32, read>;
3897 /// Example GLSL syntax:
3899 /// layout(set=0, binding=0, r32f) readonly uniform image2D myStorageImage;
3902 /// The texture can be both read and written in the shader and must be annotated with
3903 /// `read_write` in WGSL.
3905 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] must be enabled to use this access
3906 /// mode. This is a nonstandard, native-only extension.
3908 /// Example WGSL syntax:
3910 /// @group(0) @binding(0)
3911 /// var my_storage_image: texture_storage_2d<f32, read_write>;
3914 /// Example GLSL syntax:
3916 /// layout(set=0, binding=0, r32f) uniform image2D myStorageImage;
3921 /// Specific type of a sampler binding.
3923 /// For use in [`BindingType::Sampler`].
3925 /// Corresponds to [WebGPU `GPUSamplerBindingType`](
3926 /// https://gpuweb.github.io/gpuweb/#enumdef-gpusamplerbindingtype).
3928 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3929 #[cfg_attr(feature = "trace", derive(Serialize))]
3930 #[cfg_attr(feature = "replay", derive(Deserialize))]
3931 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3932 pub enum SamplerBindingType {
3933 /// The sampling result is produced based on more than a single color sample from a texture,
3934 /// e.g. when bilinear interpolation is enabled.
3936 /// The sampling result is produced based on a single color sample from a texture.
3938 /// Use as a comparison sampler instead of a normal sampler.
3939 /// For more info take a look at the analogous functionality in OpenGL: <https://www.khronos.org/opengl/wiki/Sampler_Object#Comparison_mode>.
3943 /// Specific type of a binding.
3945 /// For use in [`BindGroupLayoutEntry`].
3947 /// Corresponds to WebGPU's mutually exclusive fields within [`GPUBindGroupLayoutEntry`](
3948 /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry).
3949 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3950 #[cfg_attr(feature = "trace", derive(Serialize))]
3951 #[cfg_attr(feature = "replay", derive(Deserialize))]
3952 pub enum BindingType {
3953 /// A buffer binding.
3955 /// Corresponds to [WebGPU `GPUBufferBindingLayout`](
3956 /// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferbindinglayout).
3958 /// Sub-type of the buffer binding.
3959 ty: BufferBindingType,
3960 /// Indicates that the binding has a dynamic offset.
3962 /// One offset must be passed to [`RenderPass::set_bind_group`][RPsbg] for each dynamic
3963 /// binding in increasing order of binding number.
3965 /// [RPsbg]: ../wgpu/struct.RenderPass.html#method.set_bind_group
3966 #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
3967 has_dynamic_offset: bool,
3968 /// Minimum size of the corresponding `BufferBinding` required to match this entry.
3969 /// When pipeline is created, the size has to cover at least the corresponding structure in the shader
3970 /// plus one element of the unbound array, which can only be last in the structure.
3971 /// If `None`, the check is performed at draw call time instead of pipeline and bind group creation.
3972 #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
3973 min_binding_size: Option<BufferSize>,
3975 /// A sampler that can be used to sample a texture.
3977 /// Example WGSL syntax:
3979 /// @group(0) @binding(0)
3983 /// Example GLSL syntax:
3985 /// layout(binding = 0)
3986 /// uniform sampler s;
3989 /// Corresponds to [WebGPU `GPUSamplerBindingLayout`](
3990 /// https://gpuweb.github.io/gpuweb/#dictdef-gpusamplerbindinglayout).
3991 Sampler(SamplerBindingType),
3992 /// A texture binding.
3994 /// Example WGSL syntax:
3996 /// @group(0) @binding(0)
3997 /// var t: texture_2d<f32>;
4000 /// Example GLSL syntax:
4002 /// layout(binding = 0)
4003 /// uniform texture2D t;
4006 /// Corresponds to [WebGPU `GPUTextureBindingLayout`](
4007 /// https://gpuweb.github.io/gpuweb/#dictdef-gputexturebindinglayout).
4009 /// Sample type of the texture binding.
4010 sample_type: TextureSampleType,
4011 /// Dimension of the texture view that is going to be sampled.
4012 view_dimension: TextureViewDimension,
4013 /// True if the texture has a sample count greater than 1. If this is true,
4014 /// the texture must be read from shaders with `texture1DMS`, `texture2DMS`, or `texture3DMS`,
4015 /// depending on `dimension`.
4018 /// A storage texture.
4020 /// Example WGSL syntax:
4022 /// @group(0) @binding(0)
4023 /// var my_storage_image: texture_storage_2d<f32, write>;
4026 /// Example GLSL syntax:
4028 /// layout(set=0, binding=0, r32f) writeonly uniform image2D myStorageImage;
4030 /// Note that the texture format must be specified in the shader as well.
4031 /// A list of valid formats can be found in the specification here: <https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.html#layout-qualifiers>
4033 /// Corresponds to [WebGPU `GPUStorageTextureBindingLayout`](
4034 /// https://gpuweb.github.io/gpuweb/#dictdef-gpustoragetexturebindinglayout).
4036 /// Allowed access to this texture.
4037 access: StorageTextureAccess,
4038 /// Format of the texture.
4039 format: TextureFormat,
4040 /// Dimension of the texture view that is going to be sampled.
4041 view_dimension: TextureViewDimension,
4046 /// Returns true for buffer bindings with dynamic offset enabled.
4047 pub fn has_dynamic_offset(&self) -> bool {
4050 has_dynamic_offset, ..
4051 } => has_dynamic_offset,
4057 /// Describes a single binding inside a bind group.
4059 /// Corresponds to [WebGPU `GPUBindGroupLayoutEntry`](
4060 /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry).
4061 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4062 #[cfg_attr(feature = "trace", derive(Serialize))]
4063 #[cfg_attr(feature = "replay", derive(Deserialize))]
4064 pub struct BindGroupLayoutEntry {
4065 /// Binding index. Must match shader index and be unique inside a BindGroupLayout. A binding
4066 /// of index 1, would be described as `layout(set = 0, binding = 1) uniform` in shaders.
4068 /// Which shader stages can see this binding.
4069 pub visibility: ShaderStages,
4070 /// The type of the binding
4071 pub ty: BindingType,
4072 /// If this value is Some, indicates this entry is an array. Array size must be 1 or greater.
4074 /// If this value is Some and `ty` is `BindingType::Texture`, [`Features::TEXTURE_BINDING_ARRAY`] must be supported.
4076 /// If this value is Some and `ty` is any other variant, bind group creation will fail.
4077 #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
4078 pub count: Option<NonZeroU32>,
4081 /// View of a buffer which can be used to copy to/from a texture.
4083 /// Corresponds to [WebGPU `GPUImageCopyBuffer`](
4084 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopybuffer).
4086 #[derive(Clone, Debug)]
4087 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4088 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4089 pub struct ImageCopyBuffer<B> {
4090 /// The buffer to be copied to/from.
4092 /// The layout of the texture data in this buffer.
4093 pub layout: ImageDataLayout,
4096 /// View of a texture which can be used to copy to/from a buffer/texture.
4098 /// Corresponds to [WebGPU `GPUImageCopyTexture`](
4099 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexture).
4101 #[derive(Clone, Debug)]
4102 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4103 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4104 pub struct ImageCopyTexture<T> {
4105 /// The texture to be copied to/from.
4107 /// The target mip level of the texture.
4109 /// The base texel of the texture in the selected `mip_level`.
4110 #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
4111 pub origin: Origin3d,
4112 /// The copy aspect.
4113 #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
4114 pub aspect: TextureAspect,
4117 /// Subresource range within an image
4119 #[derive(Clone, Debug, Default, Eq, PartialEq)]
4120 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4121 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4122 pub struct ImageSubresourceRange {
4123 /// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA].
4125 /// [TAA]: ../wgpu/enum.TextureAspect.html#variant.All
4126 pub aspect: TextureAspect,
4128 pub base_mip_level: u32,
4129 /// Mip level count.
4130 /// If `Some(count)`, `base_mip_level + count` must be less or equal to underlying texture mip count.
4131 /// If `None`, considered to include the rest of the mipmap levels, but at least 1 in total.
4132 pub mip_level_count: Option<NonZeroU32>,
4133 /// Base array layer.
4134 pub base_array_layer: u32,
4136 /// If `Some(count)`, `base_array_layer + count` must be less or equal to the underlying array count.
4137 /// If `None`, considered to include the rest of the array layers, but at least 1 in total.
4138 pub array_layer_count: Option<NonZeroU32>,
4141 impl ImageSubresourceRange {
4142 /// Returns the mip level range of a subresource range describes for a specific texture.
4143 pub fn mip_range<L>(&self, texture_desc: &TextureDescriptor<L>) -> Range<u32> {
4144 self.base_mip_level..match self.mip_level_count {
4145 Some(mip_level_count) => self.base_mip_level + mip_level_count.get(),
4146 None => texture_desc.mip_level_count,
4150 /// Returns the layer range of a subresource range describes for a specific texture.
4151 pub fn layer_range<L>(&self, texture_desc: &TextureDescriptor<L>) -> Range<u32> {
4152 self.base_array_layer..match self.array_layer_count {
4153 Some(array_layer_count) => self.base_array_layer + array_layer_count.get(),
4155 if texture_desc.dimension == TextureDimension::D3 {
4156 self.base_array_layer + 1
4158 texture_desc.size.depth_or_array_layers
4165 /// Color variation to use when sampler addressing mode is [`AddressMode::ClampToBorder`]
4167 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
4168 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4169 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4170 pub enum SamplerBorderColor {
4178 /// On the Metal backend, this is equivalent to `TransparentBlack` for
4179 /// textures that have an alpha component, and equivalent to `OpaqueBlack`
4180 /// for textures that do not have an alpha component. On other backends,
4181 /// this is equivalent to `TransparentBlack`. Requires
4182 /// [`Features::ADDRESS_MODE_CLAMP_TO_ZERO`]. Not supported on the web.
4186 /// Describes how to create a QuerySet.
4188 /// Corresponds to [WebGPU `GPUQuerySetDescriptor`](
4189 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuquerysetdescriptor).
4190 #[derive(Clone, Debug)]
4191 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4192 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4193 pub struct QuerySetDescriptor<L> {
4194 /// Debug label for the query set.
4196 /// Kind of query that this query set should contain.
4198 /// Total count of queries the set contains. Must not be zero.
4199 /// Must not be greater than [`QUERY_SET_MAX_QUERIES`].
4203 impl<L> QuerySetDescriptor<L> {
4205 pub fn map_label<'a, K>(&'a self, fun: impl FnOnce(&'a L) -> K) -> QuerySetDescriptor<K> {
4206 QuerySetDescriptor {
4207 label: fun(&self.label),
4214 /// Type of query contained in a QuerySet.
4216 /// Corresponds to [WebGPU `GPUQueryType`](
4217 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuquerytype).
4218 #[derive(Copy, Clone, Debug)]
4219 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4220 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4221 pub enum QueryType {
4222 /// Query returns a single 64-bit number, serving as an occlusion boolean.
4224 /// Query returns up to 5 64-bit numbers based on the given flags.
4226 /// See [`PipelineStatisticsTypes`]'s documentation for more information
4227 /// on how they get resolved.
4229 /// [`Features::PIPELINE_STATISTICS_QUERY`] must be enabled to use this query type.
4230 PipelineStatistics(PipelineStatisticsTypes),
4231 /// Query returns a 64-bit number indicating the GPU-timestamp
4232 /// where all previous commands have finished executing.
4234 /// Must be multiplied by [`Queue::get_timestamp_period`][Qgtp] to get
4235 /// the value in nanoseconds. Absolute values have no meaning,
4236 /// but timestamps can be subtracted to get the time it takes
4237 /// for a string of operations to complete.
4239 /// [`Features::TIMESTAMP_QUERY`] must be enabled to use this query type.
4241 /// [Qgtp]: ../wgpu/struct.Queue.html#method.get_timestamp_period
4245 bitflags::bitflags! {
4246 /// Flags for which pipeline data should be recorded.
4248 /// The amount of values written when resolved depends
4249 /// on the amount of flags. If 3 flags are enabled, 3
4250 /// 64-bit values will be written per-query.
4252 /// The order they are written is the order they are declared
4253 /// in this bitflags. If you enabled `CLIPPER_PRIMITIVES_OUT`
4254 /// and `COMPUTE_SHADER_INVOCATIONS`, it would write 16 bytes,
4255 /// the first 8 bytes being the primitive out value, the last 8
4256 /// bytes being the compute shader invocation count.
4257 #[repr(transparent)]
4258 pub struct PipelineStatisticsTypes : u8 {
4259 /// Amount of times the vertex shader is ran. Accounts for
4260 /// the vertex cache when doing indexed rendering.
4261 const VERTEX_SHADER_INVOCATIONS = 1 << 0;
4262 /// Amount of times the clipper is invoked. This
4263 /// is also the amount of triangles output by the vertex shader.
4264 const CLIPPER_INVOCATIONS = 1 << 1;
4265 /// Amount of primitives that are not culled by the clipper.
4266 /// This is the amount of triangles that are actually on screen
4267 /// and will be rasterized and rendered.
4268 const CLIPPER_PRIMITIVES_OUT = 1 << 2;
4269 /// Amount of times the fragment shader is ran. Accounts for
4270 /// fragment shaders running in 2x2 blocks in order to get
4272 const FRAGMENT_SHADER_INVOCATIONS = 1 << 3;
4273 /// Amount of times a compute shader is invoked. This will
4274 /// be equivalent to the dispatch count times the workgroup size.
4275 const COMPUTE_SHADER_INVOCATIONS = 1 << 4;
4279 #[cfg(feature = "bitflags_serde_shim")]
4280 bitflags_serde_shim::impl_serde_for_bitflags!(PipelineStatisticsTypes);
4282 /// Argument buffer layout for draw_indirect commands.
4284 #[derive(Clone, Copy, Debug)]
4285 pub struct DrawIndirectArgs {
4286 /// The number of vertices to draw.
4287 pub vertex_count: u32,
4288 /// The number of instances to draw.
4289 pub instance_count: u32,
4290 /// Offset into the vertex buffers, in vertices, to begin drawing from.
4291 pub first_vertex: u32,
4292 /// First instance to draw.
4293 pub first_instance: u32,
4296 /// Argument buffer layout for draw_indexed_indirect commands.
4298 #[derive(Clone, Copy, Debug)]
4299 pub struct DrawIndexedIndirectArgs {
4300 /// The number of indices to draw.
4301 pub index_count: u32,
4302 /// The number of instances to draw.
4303 pub instance_count: u32,
4304 /// Offset into the index buffer, in indices, begin drawing from.
4305 pub first_index: u32,
4306 /// Added to each index value before indexing into the vertex buffers.
4307 pub base_vertex: i32,
4308 /// First instance to draw.
4309 pub first_instance: u32,
4312 /// Argument buffer layout for dispatch_indirect commands.
4314 #[derive(Clone, Copy, Debug)]
4315 pub struct DispatchIndirectArgs {
4316 /// X dimension of the grid of workgroups to dispatch.
4317 pub group_size_x: u32,
4318 /// Y dimension of the grid of workgroups to dispatch.
4319 pub group_size_y: u32,
4320 /// Z dimension of the grid of workgroups to dispatch.
4321 pub group_size_z: u32,
4324 /// Describes how shader bound checks should be performed.
4325 #[derive(Clone, Debug)]
4326 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4327 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4328 pub struct ShaderBoundChecks {
4329 runtime_checks: bool,
4332 impl ShaderBoundChecks {
4333 /// Creates a new configuration where the shader is bound checked.
4334 pub fn new() -> Self {
4336 runtime_checks: true,
4340 /// Creates a new configuration where the shader isn't bound checked.
4343 /// The caller MUST ensure that all shaders built with this configuration don't perform any
4344 /// out of bounds reads or writes.
4345 pub unsafe fn unchecked() -> Self {
4347 runtime_checks: false,
4351 /// Query whether runtime bound checks are enabled in this configuration
4352 pub fn runtime_checks(&self) -> bool {
4357 impl Default for ShaderBoundChecks {
4358 fn default() -> Self {