1#![doc = document_features::document_features!()]
7#![no_std]
10#![cfg_attr(
12 all(
13 not(all(feature = "vulkan", not(target_arch = "wasm32"))),
14 not(all(feature = "metal", any(target_vendor = "apple"))),
15 not(all(feature = "dx12", windows)),
16 not(feature = "gles"),
17 ),
18 allow(unused, clippy::let_and_return)
19)]
20#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
21#![allow(
22 clippy::bool_assert_comparison,
24 clippy::match_like_matches_macro,
26 clippy::redundant_pattern_matching,
28 clippy::needless_lifetimes,
30 clippy::new_without_default,
32 clippy::needless_update,
34 clippy::too_many_arguments,
36 clippy::pattern_type_mismatch,
38 rustdoc::private_intra_doc_links,
40 clippy::result_large_err
42)]
43#![warn(
44 clippy::alloc_instead_of_core,
45 clippy::ptr_as_ptr,
46 clippy::std_instead_of_alloc,
47 clippy::std_instead_of_core,
48 trivial_casts,
49 trivial_numeric_casts,
50 unsafe_op_in_unsafe_fn,
51 unused_extern_crates,
52 unused_qualifications
53)]
54#![cfg_attr(not(send_sync), allow(clippy::arc_with_non_send_sync))]
63
64extern crate alloc;
65#[cfg(feature = "std")]
66extern crate std;
67extern crate wgpu_hal as hal;
68extern crate wgpu_types as wgt;
69
70mod as_hal;
71pub mod binding_model;
72pub mod command;
73mod conv;
74pub mod device;
75pub mod error;
76pub mod global;
77mod hash_utils;
78pub mod hub;
79pub mod id;
80pub mod identity;
81mod indirect_validation;
82mod init_tracker;
83pub mod instance;
84mod lock;
85pub mod pipeline;
86mod pipeline_cache;
87mod pool;
88pub mod present;
89pub mod ray_tracing;
90pub mod registry;
91pub mod resource;
92mod snatch;
93pub mod storage;
94mod timestamp_normalization;
95mod track;
96mod weak_vec;
97mod scratch;
102pub mod validation;
103
104pub use validation::{map_storage_format_from_naga, map_storage_format_to_naga};
105
106pub use hal::{api, MAX_BIND_GROUPS, MAX_COLOR_ATTACHMENTS, MAX_VERTEX_BUFFERS};
107pub use naga;
108
109use alloc::{
110 borrow::{Cow, ToOwned as _},
111 string::String,
112};
113
114pub(crate) use hash_utils::*;
115
116pub type SubmissionIndex = hal::FenceValue;
120
121type Index = u32;
122type Epoch = u32;
123
124pub type RawString = *const core::ffi::c_char;
125pub type Label<'a> = Option<Cow<'a, str>>;
126
127trait LabelHelpers<'a> {
128 fn to_hal(&'a self, flags: wgt::InstanceFlags) -> Option<&'a str>;
129 fn to_string(&self) -> String;
130}
131impl<'a> LabelHelpers<'a> for Label<'a> {
132 fn to_hal(&'a self, flags: wgt::InstanceFlags) -> Option<&'a str> {
133 if flags.contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) {
134 return None;
135 }
136
137 self.as_deref()
138 }
139 fn to_string(&self) -> String {
140 self.as_deref().map(str::to_owned).unwrap_or_default()
141 }
142}
143
144pub fn hal_label<T: AsRef<str>>(opt: Option<T>, flags: wgt::InstanceFlags) -> Option<T> {
145 if flags.contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) {
146 return None;
147 }
148
149 opt
150}
151
152const DOWNLEVEL_WARNING_MESSAGE: &str = concat!(
153 "The underlying API or device in use does not ",
154 "support enough features to be a fully compliant implementation of WebGPU. ",
155 "A subset of the features can still be used. ",
156 "If you are running this program on native and not in a browser and wish to limit ",
157 "the features you use to the supported subset, ",
158 "call Adapter::downlevel_properties or Device::downlevel_properties to get ",
159 "a listing of the features the current ",
160 "platform supports."
161);
162
163const DOWNLEVEL_ERROR_MESSAGE: &str = concat!(
164 "This is not an invalid use of WebGPU: the underlying API or device does not ",
165 "support enough features to be a fully compliant implementation. ",
166 "A subset of the features can still be used. ",
167 "If you are running this program on native and not in a browser ",
168 "and wish to work around this issue, call ",
169 "Adapter::downlevel_properties or Device::downlevel_properties ",
170 "to get a listing of the features the current platform supports."
171);
172
173#[cfg(feature = "api_log_info")]
174macro_rules! api_log {
175 ($($arg:tt)+) => (log::info!($($arg)+))
176}
177#[cfg(not(feature = "api_log_info"))]
178macro_rules! api_log {
179 ($($arg:tt)+) => (log::trace!($($arg)+))
180}
181
182#[cfg(feature = "api_log_info")]
183macro_rules! api_log_debug {
184 ($($arg:tt)+) => (log::info!($($arg)+))
185}
186#[cfg(not(feature = "api_log_info"))]
187macro_rules! api_log_debug {
188 ($($arg:tt)+) => (log::debug!($($arg)+))
189}
190
191pub(crate) use api_log;
192pub(crate) use api_log_debug;
193
194#[cfg(feature = "resource_log_info")]
195macro_rules! resource_log {
196 ($($arg:tt)+) => (log::info!($($arg)+))
197}
198#[cfg(not(feature = "resource_log_info"))]
199macro_rules! resource_log {
200 ($($arg:tt)+) => (log::trace!($($arg)+))
201}
202pub(crate) use resource_log;
203
204#[inline]
205pub(crate) fn get_lowest_common_denom(a: u32, b: u32) -> u32 {
206 let gcd = if a >= b {
207 get_greatest_common_divisor(a, b)
208 } else {
209 get_greatest_common_divisor(b, a)
210 };
211 a * b / gcd
212}
213
214#[inline]
215pub(crate) fn get_greatest_common_divisor(mut a: u32, mut b: u32) -> u32 {
216 assert!(a >= b);
217 loop {
218 let c = a % b;
219 if c == 0 {
220 return b;
221 } else {
222 a = b;
223 b = c;
224 }
225 }
226}
227
228#[cfg(not(feature = "std"))]
229use core::cell::OnceCell as OnceCellOrLock;
230#[cfg(feature = "std")]
231use std::sync::OnceLock as OnceCellOrLock;
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236
237 #[test]
238 fn test_lcd() {
239 assert_eq!(get_lowest_common_denom(2, 2), 2);
240 assert_eq!(get_lowest_common_denom(2, 3), 6);
241 assert_eq!(get_lowest_common_denom(6, 4), 12);
242 }
243
244 #[test]
245 fn test_gcd() {
246 assert_eq!(get_greatest_common_divisor(5, 1), 1);
247 assert_eq!(get_greatest_common_divisor(4, 2), 2);
248 assert_eq!(get_greatest_common_divisor(6, 4), 2);
249 assert_eq!(get_greatest_common_divisor(7, 7), 7);
250 }
251}