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