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