1#![doc = document_features::document_features!()]
7#![cfg_attr(
11 all(
12 not(all(feature = "vulkan", not(target_arch = "wasm32"))),
13 not(all(feature = "metal", any(target_os = "macos", target_os = "ios"))),
14 not(all(feature = "dx12", windows)),
15 not(feature = "gles"),
16 ),
17 allow(unused, clippy::let_and_return)
18)]
19#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
20#![allow(
21 clippy::bool_assert_comparison,
23 clippy::match_like_matches_macro,
25 clippy::redundant_pattern_matching,
27 clippy::needless_lifetimes,
29 clippy::new_without_default,
31 clippy::needless_update,
33 clippy::too_many_arguments,
35 unused_braces,
38 clippy::pattern_type_mismatch,
40 rustdoc::private_intra_doc_links
42)]
43#![warn(
44 clippy::ptr_as_ptr,
45 trivial_casts,
46 trivial_numeric_casts,
47 unsafe_op_in_unsafe_fn,
48 unused_extern_crates,
49 unused_qualifications
50)]
51#![cfg_attr(not(send_sync), allow(clippy::arc_with_non_send_sync))]
58
59pub mod binding_model;
60pub mod command;
61mod conv;
62pub mod device;
63pub mod error;
64pub mod global;
65pub mod hal_api;
66mod hash_utils;
67pub mod hub;
68pub mod id;
69pub mod identity;
70#[cfg(feature = "indirect-validation")]
71mod indirect_validation;
72mod init_tracker;
73pub mod instance;
74mod lock;
75pub mod pipeline;
76mod pipeline_cache;
77mod pool;
78pub mod present;
79pub mod registry;
80pub mod resource;
81mod snatch;
82pub mod storage;
83mod track;
84mod weak_vec;
85pub mod validation;
90
91pub use hal::{api, MAX_BIND_GROUPS, MAX_COLOR_ATTACHMENTS, MAX_VERTEX_BUFFERS};
92pub use naga;
93
94use std::{borrow::Cow, os::raw::c_char};
95
96pub(crate) use hash_utils::*;
97
98pub type SubmissionIndex = hal::FenceValue;
102
103type Index = u32;
104type Epoch = u32;
105
106pub type RawString = *const c_char;
107pub type Label<'a> = Option<Cow<'a, str>>;
108
109trait LabelHelpers<'a> {
110 fn to_hal(&'a self, flags: wgt::InstanceFlags) -> Option<&'a str>;
111 fn to_string(&self) -> String;
112}
113impl<'a> LabelHelpers<'a> for Label<'a> {
114 fn to_hal(&'a self, flags: wgt::InstanceFlags) -> Option<&'a str> {
115 if flags.contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) {
116 return None;
117 }
118
119 self.as_ref().map(|cow| cow.as_ref())
120 }
121 fn to_string(&self) -> String {
122 self.as_ref().map(|cow| cow.to_string()).unwrap_or_default()
123 }
124}
125
126pub fn hal_label(opt: Option<&str>, flags: wgt::InstanceFlags) -> Option<&str> {
127 if flags.contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) {
128 return None;
129 }
130
131 opt
132}
133
134const DOWNLEVEL_WARNING_MESSAGE: &str = concat!(
135 "The underlying API or device in use does not ",
136 "support enough features to be a fully compliant implementation of WebGPU. ",
137 "A subset of the features can still be used. ",
138 "If you are running this program on native and not in a browser and wish to limit ",
139 "the features you use to the supported subset, ",
140 "call Adapter::downlevel_properties or Device::downlevel_properties to get ",
141 "a listing of the features the current ",
142 "platform supports."
143);
144
145const DOWNLEVEL_ERROR_MESSAGE: &str = concat!(
146 "This is not an invalid use of WebGPU: the underlying API or device does not ",
147 "support enough features to be a fully compliant implementation. ",
148 "A subset of the features can still be used. ",
149 "If you are running this program on native and not in a browser ",
150 "and wish to work around this issue, call ",
151 "Adapter::downlevel_properties or Device::downlevel_properties ",
152 "to get a listing of the features the current platform supports."
153);
154
155#[cfg(feature = "api_log_info")]
156macro_rules! api_log {
157 ($($arg:tt)+) => (log::info!($($arg)+))
158}
159#[cfg(not(feature = "api_log_info"))]
160macro_rules! api_log {
161 ($($arg:tt)+) => (log::trace!($($arg)+))
162}
163pub(crate) use api_log;
164
165#[cfg(feature = "resource_log_info")]
166macro_rules! resource_log {
167 ($($arg:tt)+) => (log::info!($($arg)+))
168}
169#[cfg(not(feature = "resource_log_info"))]
170macro_rules! resource_log {
171 ($($arg:tt)+) => (log::trace!($($arg)+))
172}
173pub(crate) use resource_log;
174
175#[inline]
176pub(crate) fn get_lowest_common_denom(a: u32, b: u32) -> u32 {
177 let gcd = if a >= b {
178 get_greatest_common_divisor(a, b)
179 } else {
180 get_greatest_common_divisor(b, a)
181 };
182 a * b / gcd
183}
184
185#[inline]
186pub(crate) fn get_greatest_common_divisor(mut a: u32, mut b: u32) -> u32 {
187 assert!(a >= b);
188 loop {
189 let c = a % b;
190 if c == 0 {
191 return b;
192 } else {
193 a = b;
194 b = c;
195 }
196 }
197}
198
199#[test]
200fn test_lcd() {
201 assert_eq!(get_lowest_common_denom(2, 2), 2);
202 assert_eq!(get_lowest_common_denom(2, 3), 6);
203 assert_eq!(get_lowest_common_denom(6, 4), 12);
204}
205
206#[test]
207fn test_gcd() {
208 assert_eq!(get_greatest_common_divisor(5, 1), 1);
209 assert_eq!(get_greatest_common_divisor(4, 2), 2);
210 assert_eq!(get_greatest_common_divisor(6, 4), 2);
211 assert_eq!(get_greatest_common_divisor(7, 7), 7);
212}