#![allow(
// The intra doc links to the wgpu crate in this crate actually succesfully link to the types in the wgpu crate, when built from the wgpu crate.
// However when building from both the wgpu crate or this crate cargo doc will claim all the links cannot be resolved
// despite the fact that it works fine when it needs to.
// So we just disable those warnings.
broken_intra_doc_links,
// We don't use syntax sugar where it's not necessary.
clippy::match_like_matches_macro,
)]
#![warn(missing_docs)]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::{num::NonZeroU32, ops::Range};
pub type BufferAddress = u64;
pub type BufferSize = std::num::NonZeroU64;
pub type ShaderLocation = u32;
pub type DynamicOffset = u32;
pub const COPY_BYTES_PER_ROW_ALIGNMENT: u32 = 256;
pub const BIND_BUFFER_ALIGNMENT: BufferAddress = 256;
pub const COPY_BUFFER_ALIGNMENT: BufferAddress = 4;
pub const MAP_ALIGNMENT: BufferAddress = 8;
pub const VERTEX_STRIDE_ALIGNMENT: BufferAddress = 4;
pub const PUSH_CONSTANT_ALIGNMENT: u32 = 4;
pub const QUERY_SET_MAX_QUERIES: u32 = 8192;
pub const QUERY_SIZE: u32 = 8;
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum Backend {
Empty = 0,
Vulkan = 1,
Metal = 2,
Dx12 = 3,
Dx11 = 4,
Gl = 5,
BrowserWebGpu = 6,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum PowerPreference {
LowPower = 0,
HighPerformance = 1,
}
impl Default for PowerPreference {
fn default() -> Self {
Self::LowPower
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BackendBit: u32 {
const VULKAN = 1 << Backend::Vulkan as u32;
const GL = 1 << Backend::Gl as u32;
const METAL = 1 << Backend::Metal as u32;
const DX12 = 1 << Backend::Dx12 as u32;
const DX11 = 1 << Backend::Dx11 as u32;
const BROWSER_WEBGPU = 1 << Backend::BrowserWebGpu as u32;
const PRIMARY = Self::VULKAN.bits
| Self::METAL.bits
| Self::DX12.bits
| Self::BROWSER_WEBGPU.bits;
const SECONDARY = Self::GL.bits | Self::DX11.bits;
}
}
impl From<Backend> for BackendBit {
fn from(backend: Backend) -> Self {
Self::from_bits(1 << backend as u32).unwrap()
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct RequestAdapterOptions<S> {
pub power_preference: PowerPreference,
pub compatible_surface: Option<S>,
}
impl<S> Default for RequestAdapterOptions<S> {
fn default() -> Self {
Self {
power_preference: PowerPreference::default(),
compatible_surface: None,
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Default)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct Features: u64 {
const DEPTH_CLAMPING = 0x0000_0000_0000_0001;
const TEXTURE_COMPRESSION_BC = 0x0000_0000_0000_0002;
const TIMESTAMP_QUERY = 0x0000_0000_0000_0004;
const PIPELINE_STATISTICS_QUERY = 0x0000_0000_0000_0008;
const MAPPABLE_PRIMARY_BUFFERS = 0x0000_0000_0001_0000;
const SAMPLED_TEXTURE_BINDING_ARRAY = 0x0000_0000_0002_0000;
const SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING = 0x0000_0000_0004_0000;
const SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0000_0008_0000;
const UNSIZED_BINDING_ARRAY = 0x0000_0000_0010_0000;
const MULTI_DRAW_INDIRECT = 0x0000_0000_0020_0000;
const MULTI_DRAW_INDIRECT_COUNT = 0x0000_0000_0040_0000;
const PUSH_CONSTANTS = 0x0000_0000_0080_0000;
const ADDRESS_MODE_CLAMP_TO_BORDER = 0x0000_0000_0100_0000;
const NON_FILL_POLYGON_MODE = 0x0000_0000_0200_0000;
const TEXTURE_COMPRESSION_ETC2 = 0x0000_0000_0400_0000;
const TEXTURE_COMPRESSION_ASTC_LDR = 0x0000_0000_0800_0000;
const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 0x0000_0000_1000_0000;
const SHADER_FLOAT64 = 0x0000_0000_2000_0000;
const VERTEX_ATTRIBUTE_64BIT = 0x0000_0000_4000_0000;
const CONSERVATIVE_RASTERIZATION = 0x0000_0000_8000_0000;
const BUFFER_BINDING_ARRAY = 0x0000_0001_0000_0000;
const UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0002_0000_0000;
const UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0004_0000_0000;
const STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0008_0000_0000;
const STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0010_0000_0000;
const ALL_WEBGPU = 0x0000_0000_0000_FFFF;
const ALL_NATIVE = 0xFFFF_FFFF_FFFF_0000;
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct Limits {
pub max_texture_dimension_1d: u32,
pub max_texture_dimension_2d: u32,
pub max_texture_dimension_3d: u32,
pub max_texture_array_layers: u32,
pub max_bind_groups: u32,
pub max_dynamic_uniform_buffers_per_pipeline_layout: u32,
pub max_dynamic_storage_buffers_per_pipeline_layout: u32,
pub max_sampled_textures_per_shader_stage: u32,
pub max_samplers_per_shader_stage: u32,
pub max_storage_buffers_per_shader_stage: u32,
pub max_storage_textures_per_shader_stage: u32,
pub max_uniform_buffers_per_shader_stage: u32,
pub max_uniform_buffer_binding_size: u32,
pub max_storage_buffer_binding_size: u32,
pub max_vertex_buffers: u32,
pub max_vertex_attributes: u32,
pub max_vertex_buffer_array_stride: u32,
pub max_push_constant_size: u32,
}
impl Default for Limits {
fn default() -> Self {
Self {
max_texture_dimension_1d: 8192,
max_texture_dimension_2d: 8192,
max_texture_dimension_3d: 2048,
max_texture_array_layers: 2048,
max_bind_groups: 4,
max_dynamic_uniform_buffers_per_pipeline_layout: 8,
max_dynamic_storage_buffers_per_pipeline_layout: 4,
max_sampled_textures_per_shader_stage: 16,
max_samplers_per_shader_stage: 16,
max_storage_buffers_per_shader_stage: 4,
max_storage_textures_per_shader_stage: 4,
max_uniform_buffers_per_shader_stage: 12,
max_uniform_buffer_binding_size: 16384,
max_storage_buffer_binding_size: 128 << 20,
max_vertex_buffers: 8,
max_vertex_attributes: 16,
max_vertex_buffer_array_stride: 2048,
max_push_constant_size: 0,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DownlevelProperties {
pub flags: DownlevelFlags,
pub shader_model: ShaderModel,
}
impl Default for DownlevelProperties {
fn default() -> Self {
Self {
flags: DownlevelFlags::COMPLIANT,
shader_model: ShaderModel::Sm5,
}
}
}
impl DownlevelProperties {
pub fn is_webgpu_compliant(self) -> bool {
self == Self::default()
}
}
bitflags::bitflags! {
pub struct DownlevelFlags: u32 {
const COMPUTE_SHADERS = 0x0000_0001;
const STORAGE_IMAGES = 0x0000_0002;
const READ_ONLY_DEPTH_STENCIL = 0x0000_0004;
const DEVICE_LOCAL_IMAGE_COPIES = 0x0000_0008;
const NON_POWER_OF_TWO_MIPMAPPED_TEXTURES = 0x0000_0010;
const ANISOTROPIC_FILTERING = 0x0000_0020;
const COMPLIANT = 0x0000_003F;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ShaderModel {
Sm2,
Sm4,
Sm5,
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum DeviceType {
Other,
IntegratedGpu,
DiscreteGpu,
VirtualGpu,
Cpu,
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct AdapterInfo {
pub name: String,
pub vendor: usize,
pub device: usize,
pub device_type: DeviceType,
pub backend: Backend,
}
#[repr(C)]
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct DeviceDescriptor<L> {
pub label: L,
pub features: Features,
pub limits: Limits,
}
impl<L> DeviceDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> DeviceDescriptor<K> {
DeviceDescriptor {
label: fun(&self.label),
features: self.features,
limits: self.limits.clone(),
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct ShaderStage: u32 {
const NONE = 0;
const VERTEX = 1;
const FRAGMENT = 2;
const VERTEX_FRAGMENT = Self::VERTEX.bits | Self::FRAGMENT.bits;
const COMPUTE = 4;
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Default)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct ShaderFlags: u32 {
const VALIDATION = 1;
const EXPERIMENTAL_TRANSLATION = 2;
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum TextureViewDimension {
D1,
D2,
D2Array,
Cube,
CubeArray,
D3,
}
impl Default for TextureViewDimension {
fn default() -> Self {
Self::D2
}
}
impl TextureViewDimension {
pub fn compatible_texture_dimension(self) -> TextureDimension {
match self {
Self::D1 => TextureDimension::D1,
Self::D2 | Self::D2Array | Self::Cube | Self::CubeArray => TextureDimension::D2,
Self::D3 => TextureDimension::D3,
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum BlendFactor {
Zero = 0,
One = 1,
Src = 2,
OneMinusSrc = 3,
SrcAlpha = 4,
OneMinusSrcAlpha = 5,
Dst = 6,
OneMinusDst = 7,
DstAlpha = 8,
OneMinusDstAlpha = 9,
SrcAlphaSaturated = 10,
Constant = 11,
OneMinusConstant = 12,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum BlendOperation {
Add = 0,
Subtract = 1,
ReverseSubtract = 2,
Min = 3,
Max = 4,
}
impl Default for BlendOperation {
fn default() -> Self {
Self::Add
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BlendComponent {
pub src_factor: BlendFactor,
pub dst_factor: BlendFactor,
pub operation: BlendOperation,
}
impl BlendComponent {
pub const REPLACE: Self = Self {
src_factor: BlendFactor::One,
dst_factor: BlendFactor::Zero,
operation: BlendOperation::Add,
};
pub const OVER: Self = Self {
src_factor: BlendFactor::One,
dst_factor: BlendFactor::OneMinusSrcAlpha,
operation: BlendOperation::Add,
};
pub fn uses_constant(&self) -> bool {
match (self.src_factor, self.dst_factor) {
(BlendFactor::Constant, _)
| (BlendFactor::OneMinusConstant, _)
| (_, BlendFactor::Constant)
| (_, BlendFactor::OneMinusConstant) => true,
(_, _) => false,
}
}
}
impl Default for BlendComponent {
fn default() -> Self {
Self::REPLACE
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BlendState {
pub color: BlendComponent,
pub alpha: BlendComponent,
}
impl BlendState {
pub const REPLACE: Self = Self {
color: BlendComponent::REPLACE,
alpha: BlendComponent::REPLACE,
};
pub const ALPHA_BLENDING: Self = Self {
color: BlendComponent {
src_factor: BlendFactor::SrcAlpha,
dst_factor: BlendFactor::OneMinusSrcAlpha,
operation: BlendOperation::Add,
},
alpha: BlendComponent::OVER,
};
pub const PREMULTIPLIED_ALPHA_BLENDING: Self = Self {
color: BlendComponent::OVER,
alpha: BlendComponent::OVER,
};
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct ColorTargetState {
pub format: TextureFormat,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub blend: Option<BlendState>,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub write_mask: ColorWrite,
}
impl From<TextureFormat> for ColorTargetState {
fn from(format: TextureFormat) -> Self {
Self {
format,
blend: None,
write_mask: ColorWrite::ALL,
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum PrimitiveTopology {
PointList = 0,
LineList = 1,
LineStrip = 2,
TriangleList = 3,
TriangleStrip = 4,
}
impl Default for PrimitiveTopology {
fn default() -> Self {
PrimitiveTopology::TriangleList
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum FrontFace {
Ccw = 0,
Cw = 1,
}
impl Default for FrontFace {
fn default() -> Self {
Self::Ccw
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum Face {
Front = 0,
Back = 1,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum PolygonMode {
Fill = 0,
Line = 1,
Point = 2,
}
impl Default for PolygonMode {
fn default() -> Self {
Self::Fill
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct PrimitiveState {
pub topology: PrimitiveTopology,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub strip_index_format: Option<IndexFormat>,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub front_face: FrontFace,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub cull_mode: Option<Face>,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub clamp_depth: bool,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub polygon_mode: PolygonMode,
pub conservative: bool,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct MultisampleState {
pub count: u32,
pub mask: u64,
pub alpha_to_coverage_enabled: bool,
}
impl Default for MultisampleState {
fn default() -> Self {
MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct TextureFormatFeatureFlags: u32 {
const STORAGE_READ_WRITE = 1;
const STORAGE_ATOMICS = 2;
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct TextureFormatFeatures {
pub allowed_usages: TextureUsage,
pub flags: TextureFormatFeatureFlags,
pub filterable: bool,
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct TextureFormatInfo {
pub required_features: Features,
pub sample_type: TextureSampleType,
pub block_dimensions: (u8, u8),
pub block_size: u8,
pub srgb: bool,
pub guaranteed_format_features: TextureFormatFeatures,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum TextureFormat {
R8Unorm = 0,
R8Snorm = 1,
R8Uint = 2,
R8Sint = 3,
R16Uint = 4,
R16Sint = 5,
R16Float = 6,
Rg8Unorm = 7,
Rg8Snorm = 8,
Rg8Uint = 9,
Rg8Sint = 10,
R32Uint = 11,
R32Sint = 12,
R32Float = 13,
Rg16Uint = 14,
Rg16Sint = 15,
Rg16Float = 16,
Rgba8Unorm = 17,
Rgba8UnormSrgb = 18,
Rgba8Snorm = 19,
Rgba8Uint = 20,
Rgba8Sint = 21,
Bgra8Unorm = 22,
Bgra8UnormSrgb = 23,
Rgb10a2Unorm = 24,
Rg11b10Float = 25,
Rg32Uint = 26,
Rg32Sint = 27,
Rg32Float = 28,
Rgba16Uint = 29,
Rgba16Sint = 30,
Rgba16Float = 31,
Rgba32Uint = 32,
Rgba32Sint = 33,
Rgba32Float = 34,
Depth32Float = 35,
Depth24Plus = 36,
Depth24PlusStencil8 = 37,
Bc1RgbaUnorm = 38,
Bc1RgbaUnormSrgb = 39,
Bc2RgbaUnorm = 40,
Bc2RgbaUnormSrgb = 41,
Bc3RgbaUnorm = 42,
Bc3RgbaUnormSrgb = 43,
Bc4RUnorm = 44,
Bc4RSnorm = 45,
Bc5RgUnorm = 46,
Bc5RgSnorm = 47,
Bc6hRgbUfloat = 48,
Bc6hRgbSfloat = 49,
Bc7RgbaUnorm = 50,
Bc7RgbaUnormSrgb = 51,
Etc2RgbUnorm = 52,
Etc2RgbUnormSrgb = 53,
Etc2RgbA1Unorm = 54,
Etc2RgbA1UnormSrgb = 55,
Etc2RgbA8Unorm = 56,
Etc2RgbA8UnormSrgb = 57,
EacRUnorm = 58,
EacRSnorm = 59,
EtcRgUnorm = 60,
EtcRgSnorm = 61,
Astc4x4RgbaUnorm = 62,
Astc4x4RgbaUnormSrgb = 63,
Astc5x4RgbaUnorm = 64,
Astc5x4RgbaUnormSrgb = 65,
Astc5x5RgbaUnorm = 66,
Astc5x5RgbaUnormSrgb = 67,
Astc6x5RgbaUnorm = 68,
Astc6x5RgbaUnormSrgb = 69,
Astc6x6RgbaUnorm = 70,
Astc6x6RgbaUnormSrgb = 71,
Astc8x5RgbaUnorm = 72,
Astc8x5RgbaUnormSrgb = 73,
Astc8x6RgbaUnorm = 74,
Astc8x6RgbaUnormSrgb = 75,
Astc10x5RgbaUnorm = 76,
Astc10x5RgbaUnormSrgb = 77,
Astc10x6RgbaUnorm = 78,
Astc10x6RgbaUnormSrgb = 79,
Astc8x8RgbaUnorm = 80,
Astc8x8RgbaUnormSrgb = 81,
Astc10x8RgbaUnorm = 82,
Astc10x8RgbaUnormSrgb = 83,
Astc10x10RgbaUnorm = 84,
Astc10x10RgbaUnormSrgb = 85,
Astc12x10RgbaUnorm = 86,
Astc12x10RgbaUnormSrgb = 87,
Astc12x12RgbaUnorm = 88,
Astc12x12RgbaUnormSrgb = 89,
}
impl TextureFormat {
pub fn describe(&self) -> TextureFormatInfo {
let native = Features::empty();
let bc = Features::TEXTURE_COMPRESSION_BC;
let etc2 = Features::TEXTURE_COMPRESSION_ETC2;
let astc_ldr = Features::TEXTURE_COMPRESSION_ASTC_LDR;
let uint = TextureSampleType::Uint;
let sint = TextureSampleType::Sint;
let nearest = TextureSampleType::Float { filterable: false };
let float = TextureSampleType::Float { filterable: true };
let depth = TextureSampleType::Depth;
let linear = false;
let srgb = true;
let basic = TextureUsage::COPY_SRC | TextureUsage::COPY_DST | TextureUsage::SAMPLED;
let attachment = basic | TextureUsage::RENDER_ATTACHMENT;
let storage = basic | TextureUsage::STORAGE;
let all_flags = TextureUsage::all();
let (required_features, sample_type, srgb, block_dimensions, block_size, allowed_usages) =
match self {
Self::R8Unorm => (native, float, linear, (1, 1), 1, attachment),
Self::R8Snorm => (native, float, linear, (1, 1), 1, basic),
Self::R8Uint => (native, uint, linear, (1, 1), 1, attachment),
Self::R8Sint => (native, sint, linear, (1, 1), 1, attachment),
Self::R16Uint => (native, uint, linear, (1, 1), 2, attachment),
Self::R16Sint => (native, sint, linear, (1, 1), 2, attachment),
Self::R16Float => (native, float, linear, (1, 1), 2, attachment),
Self::Rg8Unorm => (native, float, linear, (1, 1), 2, attachment),
Self::Rg8Snorm => (native, float, linear, (1, 1), 2, attachment),
Self::Rg8Uint => (native, uint, linear, (1, 1), 2, attachment),
Self::Rg8Sint => (native, sint, linear, (1, 1), 2, basic),
Self::R32Uint => (native, uint, linear, (1, 1), 4, all_flags),
Self::R32Sint => (native, sint, linear, (1, 1), 4, all_flags),
Self::R32Float => (native, nearest, linear, (1, 1), 4, all_flags),
Self::Rg16Uint => (native, uint, linear, (1, 1), 4, attachment),
Self::Rg16Sint => (native, sint, linear, (1, 1), 4, attachment),
Self::Rg16Float => (native, float, linear, (1, 1), 4, attachment),
Self::Rgba8Unorm => (native, float, linear, (1, 1), 4, all_flags),
Self::Rgba8UnormSrgb => (native, float, srgb, (1, 1), 4, attachment),
Self::Rgba8Snorm => (native, float, linear, (1, 1), 4, storage),
Self::Rgba8Uint => (native, uint, linear, (1, 1), 4, all_flags),
Self::Rgba8Sint => (native, sint, linear, (1, 1), 4, all_flags),
Self::Bgra8Unorm => (native, float, linear, (1, 1), 4, attachment),
Self::Bgra8UnormSrgb => (native, float, srgb, (1, 1), 4, attachment),
Self::Rgb10a2Unorm => (native, float, linear, (1, 1), 4, attachment),
Self::Rg11b10Float => (native, float, linear, (1, 1), 4, basic),
Self::Rg32Uint => (native, uint, linear, (1, 1), 8, all_flags),
Self::Rg32Sint => (native, sint, linear, (1, 1), 8, all_flags),
Self::Rg32Float => (native, nearest, linear, (1, 1), 8, all_flags),
Self::Rgba16Uint => (native, uint, linear, (1, 1), 8, all_flags),
Self::Rgba16Sint => (native, sint, linear, (1, 1), 8, all_flags),
Self::Rgba16Float => (native, float, linear, (1, 1), 8, all_flags),
Self::Rgba32Uint => (native, uint, linear, (1, 1), 16, all_flags),
Self::Rgba32Sint => (native, sint, linear, (1, 1), 16, all_flags),
Self::Rgba32Float => (native, nearest, linear, (1, 1), 16, all_flags),
Self::Depth32Float => (native, depth, linear, (1, 1), 4, attachment),
Self::Depth24Plus => (native, depth, linear, (1, 1), 4, attachment),
Self::Depth24PlusStencil8 => (native, depth, linear, (1, 1), 4, attachment),
Self::Bc1RgbaUnorm => (bc, float, linear, (4, 4), 8, basic),
Self::Bc1RgbaUnormSrgb => (bc, float, srgb, (4, 4), 8, basic),
Self::Bc2RgbaUnorm => (bc, float, linear, (4, 4), 16, basic),
Self::Bc2RgbaUnormSrgb => (bc, float, srgb, (4, 4), 16, basic),
Self::Bc3RgbaUnorm => (bc, float, linear, (4, 4), 16, basic),
Self::Bc3RgbaUnormSrgb => (bc, float, srgb, (4, 4), 16, basic),
Self::Bc4RUnorm => (bc, float, linear, (4, 4), 8, basic),
Self::Bc4RSnorm => (bc, float, linear, (4, 4), 8, basic),
Self::Bc5RgUnorm => (bc, float, linear, (4, 4), 16, basic),
Self::Bc5RgSnorm => (bc, float, linear, (4, 4), 16, basic),
Self::Bc6hRgbUfloat => (bc, float, linear, (4, 4), 16, basic),
Self::Bc6hRgbSfloat => (bc, float, linear, (4, 4), 16, basic),
Self::Bc7RgbaUnorm => (bc, float, linear, (4, 4), 16, basic),
Self::Bc7RgbaUnormSrgb => (bc, float, srgb, (4, 4), 16, basic),
Self::Etc2RgbUnorm => (etc2, float, linear, (4, 4), 8, basic),
Self::Etc2RgbUnormSrgb => (etc2, float, srgb, (4, 4), 8, basic),
Self::Etc2RgbA1Unorm => (etc2, float, linear, (4, 4), 8, basic),
Self::Etc2RgbA1UnormSrgb => (etc2, float, srgb, (4, 4), 8, basic),
Self::Etc2RgbA8Unorm => (etc2, float, linear, (4, 4), 16, basic),
Self::Etc2RgbA8UnormSrgb => (etc2, float, srgb, (4, 4), 16, basic),
Self::EacRUnorm => (etc2, float, linear, (4, 4), 8, basic),
Self::EacRSnorm => (etc2, float, linear, (4, 4), 8, basic),
Self::EtcRgUnorm => (etc2, float, linear, (4, 4), 16, basic),
Self::EtcRgSnorm => (etc2, float, linear, (4, 4), 16, basic),
Self::Astc4x4RgbaUnorm => (astc_ldr, float, linear, (4, 4), 16, basic),
Self::Astc4x4RgbaUnormSrgb => (astc_ldr, float, srgb, (4, 4), 16, basic),
Self::Astc5x4RgbaUnorm => (astc_ldr, float, linear, (5, 4), 16, basic),
Self::Astc5x4RgbaUnormSrgb => (astc_ldr, float, srgb, (5, 4), 16, basic),
Self::Astc5x5RgbaUnorm => (astc_ldr, float, linear, (5, 5), 16, basic),
Self::Astc5x5RgbaUnormSrgb => (astc_ldr, float, srgb, (5, 5), 16, basic),
Self::Astc6x5RgbaUnorm => (astc_ldr, float, linear, (6, 5), 16, basic),
Self::Astc6x5RgbaUnormSrgb => (astc_ldr, float, srgb, (6, 5), 16, basic),
Self::Astc6x6RgbaUnorm => (astc_ldr, float, linear, (6, 6), 16, basic),
Self::Astc6x6RgbaUnormSrgb => (astc_ldr, float, srgb, (6, 6), 16, basic),
Self::Astc8x5RgbaUnorm => (astc_ldr, float, linear, (8, 5), 16, basic),
Self::Astc8x5RgbaUnormSrgb => (astc_ldr, float, srgb, (8, 5), 16, basic),
Self::Astc8x6RgbaUnorm => (astc_ldr, float, linear, (8, 6), 16, basic),
Self::Astc8x6RgbaUnormSrgb => (astc_ldr, float, srgb, (8, 6), 16, basic),
Self::Astc10x5RgbaUnorm => (astc_ldr, float, linear, (10, 5), 16, basic),
Self::Astc10x5RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 5), 16, basic),
Self::Astc10x6RgbaUnorm => (astc_ldr, float, linear, (10, 6), 16, basic),
Self::Astc10x6RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 6), 16, basic),
Self::Astc8x8RgbaUnorm => (astc_ldr, float, linear, (8, 8), 16, basic),
Self::Astc8x8RgbaUnormSrgb => (astc_ldr, float, srgb, (8, 8), 16, basic),
Self::Astc10x8RgbaUnorm => (astc_ldr, float, linear, (10, 8), 16, basic),
Self::Astc10x8RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 8), 16, basic),
Self::Astc10x10RgbaUnorm => (astc_ldr, float, linear, (10, 10), 16, basic),
Self::Astc10x10RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 10), 16, basic),
Self::Astc12x10RgbaUnorm => (astc_ldr, float, linear, (12, 10), 16, basic),
Self::Astc12x10RgbaUnormSrgb => (astc_ldr, float, srgb, (12, 10), 16, basic),
Self::Astc12x12RgbaUnorm => (astc_ldr, float, linear, (12, 12), 16, basic),
Self::Astc12x12RgbaUnormSrgb => (astc_ldr, float, srgb, (12, 12), 16, basic),
};
TextureFormatInfo {
required_features,
sample_type,
block_dimensions,
block_size,
srgb,
guaranteed_format_features: TextureFormatFeatures {
allowed_usages,
flags: TextureFormatFeatureFlags::empty(),
filterable: sample_type == TextureSampleType::Float { filterable: true },
},
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct ColorWrite: u32 {
const RED = 1;
const GREEN = 2;
const BLUE = 4;
const ALPHA = 8;
const COLOR = 7;
const ALL = 15;
}
}
impl Default for ColorWrite {
fn default() -> Self {
Self::ALL
}
}
#[repr(C)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct StencilState {
pub front: StencilFaceState,
pub back: StencilFaceState,
pub read_mask: u32,
pub write_mask: u32,
}
impl StencilState {
pub fn is_enabled(&self) -> bool {
(self.front != StencilFaceState::IGNORE || self.back != StencilFaceState::IGNORE)
&& (self.read_mask != 0 || self.write_mask != 0)
}
pub fn is_read_only(&self) -> bool {
self.write_mask == 0
}
pub fn needs_ref_value(&self) -> bool {
self.front.compare.needs_ref_value() || self.back.compare.needs_ref_value()
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct DepthBiasState {
pub constant: i32,
pub slope_scale: f32,
pub clamp: f32,
}
impl DepthBiasState {
pub fn is_enabled(&self) -> bool {
self.constant != 0 || self.slope_scale != 0.0
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct DepthStencilState {
pub format: TextureFormat,
pub depth_write_enabled: bool,
pub depth_compare: CompareFunction,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub stencil: StencilState,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub bias: DepthBiasState,
}
impl DepthStencilState {
pub fn is_depth_enabled(&self) -> bool {
self.depth_compare != CompareFunction::Always || self.depth_write_enabled
}
pub fn is_read_only(&self) -> bool {
!self.depth_write_enabled && self.stencil.is_read_only()
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum IndexFormat {
Uint16 = 0,
Uint32 = 1,
}
impl Default for IndexFormat {
fn default() -> Self {
Self::Uint32
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum StencilOperation {
Keep = 0,
Zero = 1,
Replace = 2,
Invert = 3,
IncrementClamp = 4,
DecrementClamp = 5,
IncrementWrap = 6,
DecrementWrap = 7,
}
impl Default for StencilOperation {
fn default() -> Self {
Self::Keep
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct StencilFaceState {
pub compare: CompareFunction,
pub fail_op: StencilOperation,
pub depth_fail_op: StencilOperation,
pub pass_op: StencilOperation,
}
impl StencilFaceState {
pub const IGNORE: Self = StencilFaceState {
compare: CompareFunction::Always,
fail_op: StencilOperation::Keep,
depth_fail_op: StencilOperation::Keep,
pass_op: StencilOperation::Keep,
};
}
impl Default for StencilFaceState {
fn default() -> Self {
Self::IGNORE
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum CompareFunction {
Never = 1,
Less = 2,
Equal = 3,
LessEqual = 4,
Greater = 5,
NotEqual = 6,
GreaterEqual = 7,
Always = 8,
}
impl CompareFunction {
pub fn needs_ref_value(self) -> bool {
match self {
Self::Never | Self::Always => false,
_ => true,
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum InputStepMode {
Vertex = 0,
Instance = 1,
}
impl Default for InputStepMode {
fn default() -> Self {
InputStepMode::Vertex
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct VertexAttribute {
pub format: VertexFormat,
pub offset: BufferAddress,
pub shader_location: ShaderLocation,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum VertexFormat {
Uint8x2 = 0,
Uint8x4 = 1,
Sint8x2 = 2,
Sint8x4 = 3,
Unorm8x2 = 4,
Unorm8x4 = 5,
Snorm8x2 = 6,
Snorm8x4 = 7,
Uint16x2 = 8,
Uint16x4 = 9,
Sint16x2 = 10,
Sint16x4 = 11,
Unorm16x2 = 12,
Unorm16x4 = 13,
Snorm16x2 = 14,
Snorm16x4 = 15,
Float16x2 = 16,
Float16x4 = 17,
Float32 = 18,
Float32x2 = 19,
Float32x3 = 20,
Float32x4 = 21,
Uint32 = 22,
Uint32x2 = 23,
Uint32x3 = 24,
Uint32x4 = 25,
Sint32 = 26,
Sint32x2 = 27,
Sint32x3 = 28,
Sint32x4 = 29,
Float64 = 30,
Float64x2 = 31,
Float64x3 = 32,
Float64x4 = 33,
}
impl VertexFormat {
pub const fn size(&self) -> u64 {
match self {
Self::Uint8x2 | Self::Sint8x2 | Self::Unorm8x2 | Self::Snorm8x2 => 2,
Self::Uint8x4
| Self::Sint8x4
| Self::Unorm8x4
| Self::Snorm8x4
| Self::Uint16x2
| Self::Sint16x2
| Self::Unorm16x2
| Self::Snorm16x2
| Self::Float16x2
| Self::Float32
| Self::Uint32
| Self::Sint32 => 4,
Self::Uint16x4
| Self::Sint16x4
| Self::Unorm16x4
| Self::Snorm16x4
| Self::Float16x4
| Self::Float32x2
| Self::Uint32x2
| Self::Sint32x2
| Self::Float64 => 8,
Self::Float32x3 | Self::Uint32x3 | Self::Sint32x3 => 12,
Self::Float32x4 | Self::Uint32x4 | Self::Sint32x4 | Self::Float64x2 => 16,
Self::Float64x3 => 24,
Self::Float64x4 => 32,
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BufferUsage: u32 {
const MAP_READ = 1;
const MAP_WRITE = 2;
const COPY_SRC = 4;
const COPY_DST = 8;
const INDEX = 16;
const VERTEX = 32;
const UNIFORM = 64;
const STORAGE = 128;
const INDIRECT = 256;
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BufferDescriptor<L> {
pub label: L,
pub size: BufferAddress,
pub usage: BufferUsage,
pub mapped_at_creation: bool,
}
impl<L> BufferDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> BufferDescriptor<K> {
BufferDescriptor {
label: fun(&self.label),
size: self.size,
usage: self.usage,
mapped_at_creation: self.mapped_at_creation,
}
}
}
#[repr(C)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct CommandEncoderDescriptor<L> {
pub label: L,
}
impl<L> CommandEncoderDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandEncoderDescriptor<K> {
CommandEncoderDescriptor {
label: fun(&self.label),
}
}
}
impl<T> Default for CommandEncoderDescriptor<Option<T>> {
fn default() -> Self {
Self { label: None }
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum PresentMode {
Immediate = 0,
Mailbox = 1,
Fifo = 2,
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct TextureUsage: u32 {
const COPY_SRC = 1;
const COPY_DST = 2;
const SAMPLED = 4;
const STORAGE = 8;
const RENDER_ATTACHMENT = 16;
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct SwapChainDescriptor {
pub usage: TextureUsage,
pub format: TextureFormat,
pub width: u32,
pub height: u32,
pub present_mode: PresentMode,
}
#[repr(C)]
#[derive(Debug)]
pub enum SwapChainStatus {
Good,
Suboptimal,
Timeout,
Outdated,
Lost,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Color {
pub r: f64,
pub g: f64,
pub b: f64,
pub a: f64,
}
#[allow(missing_docs)]
impl Color {
pub const TRANSPARENT: Self = Self {
r: 0.0,
g: 0.0,
b: 0.0,
a: 0.0,
};
pub const BLACK: Self = Self {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
};
pub const WHITE: Self = Self {
r: 1.0,
g: 1.0,
b: 1.0,
a: 1.0,
};
pub const RED: Self = Self {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
};
pub const GREEN: Self = Self {
r: 0.0,
g: 1.0,
b: 0.0,
a: 1.0,
};
pub const BLUE: Self = Self {
r: 0.0,
g: 0.0,
b: 1.0,
a: 1.0,
};
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum TextureDimension {
D1,
D2,
D3,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct Origin3d {
pub x: u32,
pub y: u32,
pub z: u32,
}
impl Origin3d {
pub const ZERO: Self = Self { x: 0, y: 0, z: 0 };
}
impl Default for Origin3d {
fn default() -> Self {
Self::ZERO
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct Extent3d {
pub width: u32,
pub height: u32,
pub depth_or_array_layers: u32,
}
impl Default for Extent3d {
fn default() -> Self {
Self {
width: 1,
height: 1,
depth_or_array_layers: 1,
}
}
}
impl Extent3d {
pub fn physical_size(&self, format: TextureFormat) -> Self {
let (block_width, block_height) = format.describe().block_dimensions;
let block_width = block_width as u32;
let block_height = block_height as u32;
let width = ((self.width + block_width - 1) / block_width) * block_width;
let height = ((self.height + block_height - 1) / block_height) * block_height;
Self {
width,
height,
depth_or_array_layers: self.depth_or_array_layers,
}
}
pub fn max_mips(&self) -> u8 {
let max_dim = self.width.max(self.height.max(self.depth_or_array_layers));
let max_levels = 32 - max_dim.leading_zeros();
max_levels as u8
}
pub fn at_mip_level(&self, level: u8) -> Option<Self> {
let mip_count = self.max_mips();
if level >= mip_count {
return None;
}
Some(Self {
width: u32::max(1, self.width >> level as u32),
height: u32::max(1, self.height >> level as u32),
depth_or_array_layers: u32::max(1, self.depth_or_array_layers >> level as u32),
})
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct TextureDescriptor<L> {
pub label: L,
pub size: Extent3d,
pub mip_level_count: u32,
pub sample_count: u32,
pub dimension: TextureDimension,
pub format: TextureFormat,
pub usage: TextureUsage,
}
impl<L> TextureDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor<K> {
TextureDescriptor {
label: fun(&self.label),
size: self.size,
mip_level_count: self.mip_level_count,
sample_count: self.sample_count,
dimension: self.dimension,
format: self.format,
usage: self.usage,
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum TextureAspect {
All,
StencilOnly,
DepthOnly,
}
impl Default for TextureAspect {
fn default() -> Self {
Self::All
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum AddressMode {
ClampToEdge = 0,
Repeat = 1,
MirrorRepeat = 2,
ClampToBorder = 3,
}
impl Default for AddressMode {
fn default() -> Self {
Self::ClampToEdge
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum FilterMode {
Nearest = 0,
Linear = 1,
}
impl Default for FilterMode {
fn default() -> Self {
Self::Nearest
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct PushConstantRange {
pub stages: ShaderStage,
pub range: Range<u32>,
}
#[repr(C)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct CommandBufferDescriptor<L> {
pub label: L,
}
impl<L> CommandBufferDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandBufferDescriptor<K> {
CommandBufferDescriptor {
label: fun(&self.label),
}
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct RenderBundleDescriptor<L> {
pub label: L,
}
impl<L> RenderBundleDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> RenderBundleDescriptor<K> {
RenderBundleDescriptor {
label: fun(&self.label),
}
}
}
impl<T> Default for RenderBundleDescriptor<Option<T>> {
fn default() -> Self {
Self { label: None }
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct ImageDataLayout {
pub offset: BufferAddress,
pub bytes_per_row: Option<NonZeroU32>,
pub rows_per_image: Option<NonZeroU32>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum BufferBindingType {
Uniform,
Storage {
read_only: bool,
},
}
impl Default for BufferBindingType {
fn default() -> Self {
Self::Uniform
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum TextureSampleType {
Float {
filterable: bool,
},
Depth,
Sint,
Uint,
}
impl Default for TextureSampleType {
fn default() -> Self {
Self::Float { filterable: true }
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum StorageTextureAccess {
ReadOnly,
WriteOnly,
ReadWrite,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum BindingType {
Buffer {
ty: BufferBindingType,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
has_dynamic_offset: bool,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
min_binding_size: Option<BufferSize>,
},
Sampler {
filtering: bool,
comparison: bool,
},
Texture {
sample_type: TextureSampleType,
view_dimension: TextureViewDimension,
multisampled: bool,
},
StorageTexture {
access: StorageTextureAccess,
format: TextureFormat,
view_dimension: TextureViewDimension,
},
}
impl BindingType {
pub fn has_dynamic_offset(&self) -> bool {
match *self {
Self::Buffer {
has_dynamic_offset, ..
} => has_dynamic_offset,
_ => false,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BindGroupLayoutEntry {
pub binding: u32,
pub visibility: ShaderStage,
pub ty: BindingType,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub count: Option<NonZeroU32>,
}
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct ImageCopyBuffer<B> {
pub buffer: B,
pub layout: ImageDataLayout,
}
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct ImageCopyTexture<T> {
pub texture: T,
pub mip_level: u32,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
pub origin: Origin3d,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum SamplerBorderColor {
TransparentBlack,
OpaqueBlack,
OpaqueWhite,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct QuerySetDescriptor {
pub ty: QueryType,
pub count: u32,
}
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum QueryType {
PipelineStatistics(PipelineStatisticsTypes),
Timestamp,
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct PipelineStatisticsTypes : u8 {
const VERTEX_SHADER_INVOCATIONS = 0x01;
const CLIPPER_INVOCATIONS = 0x02;
const CLIPPER_PRIMITIVES_OUT = 0x04;
const FRAGMENT_SHADER_INVOCATIONS = 0x08;
const COMPUTE_SHADER_INVOCATIONS = 0x10;
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct DrawIndirectArgs {
pub vertex_count: u32,
pub instance_count: u32,
pub first_vertex: u32,
pub first_instance: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct DrawIndexedIndirectArgs {
pub index_count: u32,
pub instance_count: u32,
pub first_index: u32,
pub base_vertex: i32,
pub first_instance: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct DispatchIndirectArgs {
pub group_size_x: u32,
pub group_size_y: u32,
pub group_size_z: u32,
}