#![cfg_attr(docsrs, feature(doc_cfg))]
#![allow(
// We don't use syntax sugar where it's not necessary.
clippy::match_like_matches_macro,
)]
#![warn(
clippy::ptr_as_ptr,
missing_docs,
unsafe_op_in_unsafe_fn,
unused_qualifications
)]
#![no_std]
#[cfg(feature = "std")]
extern crate std;
extern crate alloc;
use core::{fmt, hash::Hash, time::Duration};
#[cfg(any(feature = "serde", test))]
use serde::{Deserialize, Serialize};
mod adapter;
pub mod assertions;
mod backend;
mod binding;
mod buffer;
mod cast_utils;
mod counters;
mod device;
mod env;
pub mod error;
mod features;
pub mod instance;
mod limits;
pub mod math;
mod origin_extent;
mod ray_tracing;
mod render;
#[doc(hidden)] mod send_sync;
mod shader;
mod surface;
mod texture;
mod tokens;
mod transfers;
mod vertex;
mod write_only;
pub use adapter::*;
pub use backend::*;
pub use binding::*;
pub use buffer::*;
pub use counters::*;
pub use device::*;
pub use features::*;
pub use instance::*;
pub use limits::*;
pub use origin_extent::*;
pub use ray_tracing::*;
pub use render::*;
#[doc(hidden)]
pub use send_sync::*;
pub use shader::*;
pub use surface::*;
pub use texture::*;
pub use tokens::*;
pub use transfers::*;
pub use vertex::*;
pub use write_only::*;
#[cfg(not(docsrs))]
macro_rules! link_to_wgpu_docs {
([$reference:expr]: $url_path:expr) => {
concat!("[", $reference, "]: ../wgpu/", $url_path)
};
(../ [$reference:expr]: $url_path:expr) => {
concat!("[", $reference, "]: ../../wgpu/", $url_path)
};
}
#[cfg(docsrs)]
macro_rules! link_to_wgpu_docs {
($(../)? [$reference:expr]: $url_path:expr) => {
concat!(
"[",
$reference,
"]: /wgpu/",
env!("CARGO_PKG_VERSION_MAJOR"),
"/wgpu/",
$url_path
)
};
}
macro_rules! link_to_wgpu_item {
($kind:ident $name:ident) => {
$crate::link_to_wgpu_docs!(
[concat!("`", stringify!($name), "`")]: concat!(stringify!($kind), ".", stringify!($name), ".html")
)
};
}
pub(crate) use {link_to_wgpu_docs, link_to_wgpu_item};
#[doc = link_to_wgpu_item!(struct Buffer)]
pub type BufferAddress = u64;
#[doc = link_to_wgpu_item!(struct Buffer)]
#[doc = link_to_wgpu_item!(struct BufferSlice)]
pub type BufferSize = core::num::NonZeroU64;
#[doc = link_to_wgpu_item!(struct VertexAttribute)]
pub type ShaderLocation = u32;
pub type DynamicOffset = u32;
#[doc = link_to_wgpu_docs!(["`copy_buffer_to_texture()`"]: "struct.Queue.html#method.copy_buffer_to_texture")]
#[doc = link_to_wgpu_docs!(["`copy_texture_to_buffer()`"]: "struct.Queue.html#method.copy_texture_to_buffer")]
#[doc = link_to_wgpu_docs!(["Qwt"]: "struct.Queue.html#method.write_texture")]
pub const COPY_BYTES_PER_ROW_ALIGNMENT: u32 = 256;
#[doc = link_to_wgpu_docs!(["offset into the query resolve buffer"]: "struct.CommandEncoder.html#method.resolve_query_set")]
pub const QUERY_RESOLVE_BUFFER_ALIGNMENT: BufferAddress = 256;
pub const COPY_BUFFER_ALIGNMENT: BufferAddress = 4;
#[doc = link_to_wgpu_docs!(["`map_async()`"]: "struct.Buffer.html#method.map_async")]
#[doc = link_to_wgpu_docs!(["`get_mapped_range()`"]: "struct.Buffer.html#method.get_mapped_range")]
pub const MAP_ALIGNMENT: BufferAddress = 8;
#[doc = link_to_wgpu_docs!(["Vertex buffer offsets"]: "util/trait.RenderEncoder.html#tymethod.set_vertex_buffer")]
#[doc = link_to_wgpu_docs!(["strides"]: "struct.VertexBufferLayout.html#structfield.array_stride")]
pub const VERTEX_ALIGNMENT: BufferAddress = 4;
#[doc = link_to_wgpu_docs!(["Vertex buffer strides"]: "struct.VertexBufferLayout.html#structfield.array_stride")]
#[deprecated(note = "Use `VERTEX_ALIGNMENT` instead", since = "27.0.0")]
pub const VERTEX_STRIDE_ALIGNMENT: BufferAddress = 4;
#[doc = link_to_wgpu_docs!(["writes to immediate data"]: "struct.RenderPass.html#method.set_immediates")]
pub const IMMEDIATE_DATA_ALIGNMENT: u32 = 4;
#[doc(hidden)]
pub const STORAGE_BINDING_SIZE_ALIGNMENT: u32 = 4;
pub const QUERY_SET_MAX_QUERIES: u32 = 4096;
#[doc = link_to_wgpu_docs!(["query"]: "struct.QuerySet.html")]
pub const QUERY_SIZE: u32 = 8;
pub const MINIMUM_SUBGROUP_MIN_SIZE: u32 = 4;
pub const MAXIMUM_SUBGROUP_MAX_SIZE: u32 = 128;
#[derive(Clone, Debug)]
pub enum PollType<T> {
Wait {
submission_index: Option<T>,
timeout: Option<Duration>,
},
Poll,
}
impl<T> PollType<T> {
#[must_use]
pub const fn wait_indefinitely() -> Self {
Self::Wait {
submission_index: None,
timeout: None,
}
}
#[must_use]
pub fn is_wait(&self) -> bool {
match *self {
Self::Wait { .. } => true,
Self::Poll => false,
}
}
#[must_use]
pub fn map_index<U, F>(self, func: F) -> PollType<U>
where
F: FnOnce(T) -> U,
{
match self {
Self::Wait {
submission_index,
timeout,
} => PollType::Wait {
submission_index: submission_index.map(func),
timeout,
},
Self::Poll => PollType::Poll,
}
}
}
#[derive(Debug)]
pub enum PollError {
Timeout,
WrongSubmissionIndex(u64, u64),
}
impl fmt::Display for PollError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PollError::Timeout => {
f.write_str("The requested Wait timed out before the submission was completed.")
}
PollError::WrongSubmissionIndex(requested, successful) => write!(
f,
"Tried to wait using a submission index ({requested}) \
that has not been returned by a successful submission \
(last successful submission: {successful}"
),
}
}
}
impl core::error::Error for PollError {}
#[derive(Debug, PartialEq, Eq)]
pub enum PollStatus {
QueueEmpty,
WaitSucceeded,
Poll,
}
impl PollStatus {
#[must_use]
pub fn is_queue_empty(&self) -> bool {
matches!(self, Self::QueueEmpty)
}
#[must_use]
pub fn wait_finished(&self) -> bool {
matches!(self, Self::WaitSucceeded | Self::QueueEmpty)
}
}
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct CommandEncoderDescriptor<L> {
pub label: L,
}
impl<L> CommandEncoderDescriptor<L> {
#[must_use]
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(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
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(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CommandBufferDescriptor<L> {
pub label: L,
}
impl<L> CommandBufferDescriptor<L> {
#[must_use]
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandBufferDescriptor<K> {
CommandBufferDescriptor {
label: fun(&self.label),
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct QuerySetDescriptor<L> {
pub label: L,
pub ty: QueryType,
pub count: u32,
}
impl<L> QuerySetDescriptor<L> {
#[must_use]
pub fn map_label<'a, K>(&'a self, fun: impl FnOnce(&'a L) -> K) -> QuerySetDescriptor<K> {
QuerySetDescriptor {
label: fun(&self.label),
ty: self.ty,
count: self.count,
}
}
}
#[doc = link_to_wgpu_item!(struct QuerySet)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum QueryType {
#[doc = link_to_wgpu_docs!(["`RenderPassDescriptor::occlusion_query_set`"]: "struct.RenderPassDescriptor.html#structfield.occlusion_query_set")]
#[doc = link_to_wgpu_docs!(["`RenderPass::begin_occlusion_query()`"]: "struct.RenderPass.html#structfield.begin_occlusion_query")]
#[doc = link_to_wgpu_docs!(["`RenderPass::end_occlusion_query()`"]: "struct.RenderPass.html#structfield.end_occlusion_query")]
Occlusion,
#[doc = link_to_wgpu_docs!(["`CommandEncoder::write_timestamp()`"]: "struct.CommandEncoder.html#method.write_timestamp")]
#[doc = link_to_wgpu_docs!(["`ComputePass::write_timestamp()`"]: "struct.ComputePass.html#method.write_timestamp")]
#[doc = link_to_wgpu_docs!(["`RenderPass::write_timestamp()`"]: "struct.RenderPass.html#method.write_timestamp")]
#[doc = link_to_wgpu_docs!(["`ComputePassDescriptor::timestamp_writes`"]: "struct.ComputePassDescriptor.html#structfield.timestamp_writes")]
#[doc = link_to_wgpu_docs!(["`RenderPassDescriptor::timestamp_writes`"]: "struct.RenderPassDescriptor.html#structfield.timestamp_writes")]
#[doc = link_to_wgpu_docs!(["Qgtp"]: "struct.Queue.html#method.get_timestamp_period")]
Timestamp,
#[doc = link_to_wgpu_docs!(["`ComputePass::begin_pipeline_statistics_query()`"]: "struct.ComputePass.html#method.begin_pipeline_statistics_query")]
#[doc = link_to_wgpu_docs!(["`RenderPass::begin_pipeline_statistics_query()`"]: "struct.RenderPass.html#method.begin_pipeline_statistics_query")]
PipelineStatistics(PipelineStatisticsTypes),
}
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct PipelineStatisticsTypes : u8 {
const VERTEX_SHADER_INVOCATIONS = 1 << 0;
const CLIPPER_INVOCATIONS = 1 << 1;
const CLIPPER_PRIMITIVES_OUT = 1 << 2;
const FRAGMENT_SHADER_INVOCATIONS = 1 << 3;
const COMPUTE_SHADER_INVOCATIONS = 1 << 4;
}
}
#[repr(u8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum DeviceLostReason {
Unknown = 0,
Destroyed = 1,
}