From 8c3b38f37aaf3afd467cdc59d95192be7a7101d5 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Wed, 23 Apr 2025 13:38:56 +1000 Subject: [PATCH 01/11] MVP `no_std` support in `wgpu-hal` --- .github/workflows/ci.yml | 2 ++ Cargo.lock | 1 + Cargo.toml | 2 +- deno_webgpu/Cargo.toml | 2 +- examples/features/Cargo.toml | 1 + player/Cargo.toml | 2 +- tests/Cargo.toml | 1 + wgpu-hal/Cargo.toml | 10 +++++-- wgpu-hal/src/auxil/dxgi/exception.rs | 1 + wgpu-hal/src/gles/mod.rs | 1 + wgpu-hal/src/lib.rs | 43 ++++------------------------ wgpu-hal/src/validation_canary.rs | 39 +++++++++++++++++++++++++ wgpu-hal/src/vulkan/instance.rs | 1 + 13 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 wgpu-hal/src/validation_canary.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e5030c153d..19de6f5896a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -301,9 +301,11 @@ jobs: # check with no features cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-types --no-default-features + cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-hal --no-default-features # Check with all features except "std". cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-types --no-default-features --features strict_asserts,fragile-send-sync-non-atomic-wasm,serde,counters + cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-hal --no-default-features --features fragile-send-sync-non-atomic-wasm # Building for native platforms with standard tests. - name: Check native diff --git a/Cargo.lock b/Cargo.lock index 509c9aa2176..5d67e800fc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4919,6 +4919,7 @@ dependencies = [ "wasm-bindgen-test", "web-sys", "wgpu", + "wgpu-hal", "wgpu-macros", ] diff --git a/Cargo.toml b/Cargo.toml index 0d425aeea2b..0c0e65287b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,7 +74,7 @@ wgpu-core = { version = "25.0.0", path = "./wgpu-core" } wgpu-hal = { version = "25.0.0", path = "./wgpu-hal" } wgpu-macros = { version = "25.0.0", path = "./wgpu-macros" } wgpu-test = { version = "25.0.0", path = "./tests" } -wgpu-types = { version = "25.0.0", path = "./wgpu-types" } +wgpu-types = { version = "25.0.0", path = "./wgpu-types", default-features = false } wgpu-core-deps-windows-linux-android = { version = "25.0.0", path = "./wgpu-core/platform-deps/windows-linux-android" } wgpu-core-deps-apple = { version = "25.0.0", path = "./wgpu-core/platform-deps/apple" } diff --git a/deno_webgpu/Cargo.toml b/deno_webgpu/Cargo.toml index 29786bf4c11..08545ef8d2a 100644 --- a/deno_webgpu/Cargo.toml +++ b/deno_webgpu/Cargo.toml @@ -25,7 +25,7 @@ wgpu-core = { workspace = true, features = [ "wgsl", "gles", ] } -wgpu-types = { workspace = true, features = ["serde"] } +wgpu-types = { workspace = true, features = ["serde", "std"] } deno_core.workspace = true deno_error.workspace = true diff --git a/examples/features/Cargo.toml b/examples/features/Cargo.toml index 2df3ca318cf..93ca92b37dc 100644 --- a/examples/features/Cargo.toml +++ b/examples/features/Cargo.toml @@ -45,6 +45,7 @@ png.workspace = true pollster.workspace = true web-time.workspace = true wgpu-types = { workspace = true, features = [ + "std", "trace", # TODO(#5974): this should be a dep on wgpu/trace and not wgpu-types at all ] } winit.workspace = true diff --git a/player/Cargo.toml b/player/Cargo.toml index 0f0346ece7b..aadf4e5e8ff 100644 --- a/player/Cargo.toml +++ b/player/Cargo.toml @@ -19,7 +19,7 @@ name = "play" test = false [dependencies] -wgpu-types = { workspace = true, features = ["serde"] } +wgpu-types = { workspace = true, features = ["serde", "std"] } env_logger.workspace = true log.workspace = true diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 5c206d4ba80..5e741847e50 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -32,6 +32,7 @@ webgl = ["wgpu/webgl"] [dependencies] wgpu = { workspace = true, features = ["noop"] } +wgpu-hal = { workspace = true, features = ["validation_canary"] } wgpu-macros.workspace = true anyhow.workspace = true diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 8ec740d60f6..ffeeb988c85 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -81,6 +81,7 @@ metal = [ "dep:log", "dep:metal", "dep:objc", + "dep:parking_lot", "dep:profiling", ] vulkan = [ @@ -96,6 +97,7 @@ vulkan = [ "dep:libloading", "dep:log", "dep:ordered-float", + "dep:parking_lot", "dep:profiling", "dep:smallvec", "dep:windows", @@ -115,6 +117,7 @@ gles = [ "dep:log", "dep:ndk-sys", "dep:objc", + "dep:parking_lot", "dep:profiling", "dep:wasm-bindgen", "dep:web-sys", @@ -133,6 +136,7 @@ dx12 = [ "dep:libloading", "dep:log", "dep:ordered-float", + "dep:parking_lot", "dep:profiling", "dep:range-alloc", "dep:windows-core", @@ -174,6 +178,8 @@ device_lost_panic = [] # # Only affects the d3d12 and vulkan backends. internal_error_panic = [] +# Tracks validation errors in a `VALIDATION_CANARY` static. +validation_canary = ["dep:parking_lot"] ################### ### Workarounds ### @@ -196,12 +202,12 @@ required-features = ["gles"] [dependencies] naga.workspace = true -wgpu-types.workspace = true +wgpu-types = { workspace = true, default-features = false } # Dependencies in the lib and empty backend bitflags.workspace = true raw-window-handle.workspace = true -parking_lot.workspace = true +parking_lot = { workspace = true, optional = true } thiserror.workspace = true # Target agnostic dependencies used only in backends. diff --git a/wgpu-hal/src/auxil/dxgi/exception.rs b/wgpu-hal/src/auxil/dxgi/exception.rs index dcc8cc9a4b4..537f6c10a20 100644 --- a/wgpu-hal/src/auxil/dxgi/exception.rs +++ b/wgpu-hal/src/auxil/dxgi/exception.rs @@ -86,6 +86,7 @@ unsafe extern "system" fn output_debug_string_handler( log::log!(level, "{}", message); }); + #[cfg(feature = "validation_canary")] if cfg!(debug_assertions) && level == log::Level::Error { // Set canary and continue crate::VALIDATION_CANARY.add(message.to_string()); diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 94b169daa15..a33cc7216c7 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -1086,6 +1086,7 @@ fn gl_debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, m ); }); + #[cfg(feature = "validation_canary")] if cfg!(debug_assertions) && log_severity == log::Level::Error { // Set canary and continue crate::VALIDATION_CANARY.add(message.to_string()); diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 7618b0ea3e6..cb4d2332859 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -276,6 +276,12 @@ pub mod api { mod dynamic; +#[cfg(feature = "validation_canary")] +mod validation_canary; + +#[cfg(feature = "validation_canary")] +pub use validation_canary::{ValidationCanary, VALIDATION_CANARY}; + pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ DynAccelerationStructure, DynAcquiredSurfaceTexture, DynAdapter, DynBindGroup, @@ -298,7 +304,6 @@ use core::{ }; use bitflags::bitflags; -use parking_lot::Mutex; use thiserror::Error; use wgt::WasmNotSendSync; @@ -2374,42 +2379,6 @@ pub struct ComputePassDescriptor<'a, Q: DynQuerySet + ?Sized> { pub timestamp_writes: Option>, } -/// Stores the text of any validation errors that have occurred since -/// the last call to `get_and_reset`. -/// -/// Each value is a validation error and a message associated with it, -/// or `None` if the error has no message from the api. -/// -/// This is used for internal wgpu testing only and _must not_ be used -/// as a way to check for errors. -/// -/// This works as a static because `cargo nextest` runs all of our -/// tests in separate processes, so each test gets its own canary. -/// -/// This prevents the issue of one validation error terminating the -/// entire process. -pub static VALIDATION_CANARY: ValidationCanary = ValidationCanary { - inner: Mutex::new(Vec::new()), -}; - -/// Flag for internal testing. -pub struct ValidationCanary { - inner: Mutex>, -} - -impl ValidationCanary { - #[allow(dead_code)] // in some configurations this function is dead - fn add(&self, msg: String) { - self.inner.lock().push(msg); - } - - /// Returns any API validation errors that have occurred in this process - /// since the last call to this function. - pub fn get_and_reset(&self) -> Vec { - self.inner.lock().drain(..).collect() - } -} - #[test] fn test_default_limits() { let limits = wgt::Limits::default(); diff --git a/wgpu-hal/src/validation_canary.rs b/wgpu-hal/src/validation_canary.rs new file mode 100644 index 00000000000..65b197e2097 --- /dev/null +++ b/wgpu-hal/src/validation_canary.rs @@ -0,0 +1,39 @@ +use alloc::{string::String, vec::Vec}; + +use parking_lot::Mutex; + +/// Stores the text of any validation errors that have occurred since +/// the last call to `get_and_reset`. +/// +/// Each value is a validation error and a message associated with it, +/// or `None` if the error has no message from the api. +/// +/// This is used for internal wgpu testing only and _must not_ be used +/// as a way to check for errors. +/// +/// This works as a static because `cargo nextest` runs all of our +/// tests in separate processes, so each test gets its own canary. +/// +/// This prevents the issue of one validation error terminating the +/// entire process. +pub static VALIDATION_CANARY: ValidationCanary = ValidationCanary { + inner: Mutex::new(Vec::new()), +}; + +/// Flag for internal testing. +pub struct ValidationCanary { + inner: Mutex>, +} + +impl ValidationCanary { + #[allow(dead_code)] // in some configurations this function is dead + fn add(&self, msg: String) { + self.inner.lock().push(msg); + } + + /// Returns any API validation errors that have occurred in this process + /// since the last call to this function. + pub fn get_and_reset(&self) -> Vec { + self.inner.lock().drain(..).collect() + } +} diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 6426e4b6eaa..32625f757fe 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -145,6 +145,7 @@ unsafe extern "system" fn debug_utils_messenger_callback( }); } + #[cfg(feature = "validation_canary")] if cfg!(debug_assertions) && level == log::Level::Error { // Set canary and continue crate::VALIDATION_CANARY.add(message.to_string()); From cf06ad4879d3a0091a91c2c776552fa18b419d3f Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Wed, 23 Apr 2025 13:46:35 +1000 Subject: [PATCH 02/11] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 944af456538..9b9e1111170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,10 @@ Naga now infers the correct binding layout when a resource appears only in an as - Remove the need for dxil.dll. By @teoxoy in [#7566](https://github.com/gfx-rs/wgpu/pull/7566) +#### HAL + +- Added initial `no_std` support to `wgpu-hal`. By @bushrat011899 in [#7599](https://github.com/gfx-rs/wgpu/pull/7599) + ### Bug Fixes #### Naga From ca6ace151422f5e041d81208908bedd2f1adb8e2 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Wed, 23 Apr 2025 13:47:49 +1000 Subject: [PATCH 03/11] Fix visibility --- wgpu-hal/src/validation_canary.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-hal/src/validation_canary.rs b/wgpu-hal/src/validation_canary.rs index 65b197e2097..37e41754863 100644 --- a/wgpu-hal/src/validation_canary.rs +++ b/wgpu-hal/src/validation_canary.rs @@ -27,7 +27,7 @@ pub struct ValidationCanary { impl ValidationCanary { #[allow(dead_code)] // in some configurations this function is dead - fn add(&self, msg: String) { + pub(crate) fn add(&self, msg: String) { self.inner.lock().push(msg); } From fe3cae4b6c930d6c173b080eede5e2bc1e8d8e1f Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Wed, 23 Apr 2025 13:52:41 +1000 Subject: [PATCH 04/11] Fix unused imports --- wgpu-hal/src/auxil/dxgi/exception.rs | 8 ++++---- wgpu-hal/src/vulkan/instance.rs | 12 ++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/wgpu-hal/src/auxil/dxgi/exception.rs b/wgpu-hal/src/auxil/dxgi/exception.rs index 537f6c10a20..65bec3b43ca 100644 --- a/wgpu-hal/src/auxil/dxgi/exception.rs +++ b/wgpu-hal/src/auxil/dxgi/exception.rs @@ -1,11 +1,11 @@ -use alloc::{ - borrow::Cow, - string::{String, ToString as _}, -}; +use alloc::{borrow::Cow, string::String}; use parking_lot::Mutex; use windows::Win32::{Foundation, System::Diagnostics::Debug}; +#[cfg(feature = "validation_canary")] +use alloc::string::ToString as _; + // This is a mutex as opposed to an atomic as we need to completely // lock everyone out until we have registered or unregistered the // exception handler, otherwise really nasty races could happen. diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 32625f757fe..892a775f025 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -1,11 +1,4 @@ -use alloc::{ - borrow::ToOwned as _, - boxed::Box, - ffi::CString, - string::{String, ToString as _}, - sync::Arc, - vec::Vec, -}; +use alloc::{borrow::ToOwned as _, boxed::Box, ffi::CString, string::String, sync::Arc, vec::Vec}; use core::{ ffi::{c_void, CStr}, slice, @@ -17,6 +10,9 @@ use arrayvec::ArrayVec; use ash::{ext, khr, vk}; use parking_lot::RwLock; +#[cfg(feature = "validation_canary")] +use alloc::string::ToString as _; + unsafe extern "system" fn debug_utils_messenger_callback( message_severity: vk::DebugUtilsMessageSeverityFlagsEXT, message_type: vk::DebugUtilsMessageTypeFlagsEXT, From 30fc50832f375b6e2f18925fdd7e869dabf7f88f Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Fri, 30 May 2025 08:57:47 +1000 Subject: [PATCH 05/11] Response to feedback Co-Authored-By: Connor Fitzgerald --- wgpu-hal/src/auxil/dxgi/exception.rs | 5 ++--- wgpu-hal/src/lib.rs | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/auxil/dxgi/exception.rs b/wgpu-hal/src/auxil/dxgi/exception.rs index 65bec3b43ca..b938da31ffa 100644 --- a/wgpu-hal/src/auxil/dxgi/exception.rs +++ b/wgpu-hal/src/auxil/dxgi/exception.rs @@ -3,9 +3,6 @@ use alloc::{borrow::Cow, string::String}; use parking_lot::Mutex; use windows::Win32::{Foundation, System::Diagnostics::Debug}; -#[cfg(feature = "validation_canary")] -use alloc::string::ToString as _; - // This is a mutex as opposed to an atomic as we need to completely // lock everyone out until we have registered or unregistered the // exception handler, otherwise really nasty races could happen. @@ -88,6 +85,8 @@ unsafe extern "system" fn output_debug_string_handler( #[cfg(feature = "validation_canary")] if cfg!(debug_assertions) && level == log::Level::Error { + use alloc::string::ToString as _; + // Set canary and continue crate::VALIDATION_CANARY.add(message.to_string()); } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index cb4d2332859..19fce4e5de1 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -275,7 +275,6 @@ pub mod api { } mod dynamic; - #[cfg(feature = "validation_canary")] mod validation_canary; From d8e10b689fb86cf8e4dc119a32813954bfb2dc98 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Fri, 30 May 2025 13:17:14 +1000 Subject: [PATCH 06/11] Update other `validation_canary` usages Co-Authored-By: Connor Fitzgerald --- wgpu-hal/src/vulkan/instance.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 19293362056..d946b2848c1 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -10,9 +10,6 @@ use arrayvec::ArrayVec; use ash::{ext, khr, vk}; use parking_lot::RwLock; -#[cfg(feature = "validation_canary")] -use alloc::string::ToString as _; - unsafe extern "system" fn debug_utils_messenger_callback( message_severity: vk::DebugUtilsMessageSeverityFlagsEXT, message_type: vk::DebugUtilsMessageTypeFlagsEXT, @@ -143,6 +140,8 @@ unsafe extern "system" fn debug_utils_messenger_callback( #[cfg(feature = "validation_canary")] if cfg!(debug_assertions) && level == log::Level::Error { + use alloc::string::ToString as _; + // Set canary and continue crate::VALIDATION_CANARY.add(message.to_string()); } From d280e6048501ede31f007dd71e56d99ed66178fe Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Fri, 30 May 2025 13:35:46 +1000 Subject: [PATCH 07/11] Fix `portable-atomic` feature in `naga` and `wgpu-hal` --- Cargo.lock | 5 ++++- Cargo.toml | 1 + naga/Cargo.toml | 2 ++ wgpu-hal/Cargo.toml | 18 ++++++++++++------ wgpu-hal/build.rs | 3 ++- wgpu-hal/src/lib.rs | 21 +++++++++++++++++++-- wgpu-hal/src/noop/buffer.rs | 10 +++++++++- 7 files changed, 49 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5774d3d1f9..d5616a0ba62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2962,6 +2962,9 @@ name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +dependencies = [ + "portable-atomic", +] [[package]] name = "oorandom" @@ -4927,10 +4930,10 @@ dependencies = [ "naga", "ndk-sys 0.6.0+11769913", "objc", - "once_cell", "ordered-float", "parking_lot", "portable-atomic", + "portable-atomic-util", "profiling", "range-alloc", "raw-window-handle 0.5.2", diff --git a/Cargo.toml b/Cargo.toml index ddf412c74b0..1b81fdbcb78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -160,6 +160,7 @@ pico-args = { version = "0.5", features = [ png = "0.17.6" pollster = "0.4" portable-atomic = "1.2" +portable-atomic-util = "0.2.4" pp-rs = "0.2.1" profiling = { version = "1", default-features = false } quote = "1.0.38" diff --git a/naga/Cargo.toml b/naga/Cargo.toml index 9c5c0353721..b007100d8eb 100644 --- a/naga/Cargo.toml +++ b/naga/Cargo.toml @@ -80,6 +80,8 @@ termcolor = ["codespan-reporting/termcolor"] ## Enables writing output to stderr. stderr = ["codespan-reporting/std"] +portable-atomic = ["once_cell/portable-atomic"] + [dependencies] arbitrary = { workspace = true, features = ["derive"], optional = true } arrayvec.workspace = true diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 07c52ddadbd..e8dc343539d 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -107,7 +107,6 @@ gles = [ "naga/glsl-out", "dep:arrayvec", "dep:bytemuck", - "dep:cfg-if", "dep:glow", "dep:glutin_wgl_sys", "dep:hashbrown", @@ -165,7 +164,11 @@ renderdoc = ["dep:libloading", "dep:renderdoc-sys", "dep:log"] fragile-send-sync-non-atomic-wasm = [ "wgpu-types/fragile-send-sync-non-atomic-wasm", ] -portable-atomic = ["dep:portable-atomic"] +portable-atomic = [ + "dep:portable-atomic", + "dep:portable-atomic-util", + "naga/portable-atomic", +] ################################### ### Internal Debugging Features ### @@ -207,6 +210,7 @@ wgpu-types = { workspace = true, default-features = false } # Dependencies in the lib and empty backend bitflags.workspace = true +cfg-if.workspace = true raw-window-handle.workspace = true parking_lot = { workspace = true, optional = true } thiserror.workspace = true @@ -216,14 +220,12 @@ arrayvec = { workspace = true, optional = true } bytemuck = { workspace = true, optional = true, features = ["derive"] } hashbrown = { workspace = true, optional = true } log = { workspace = true, optional = true } -once_cell = { workspace = true, optional = true } ordered-float = { workspace = true, optional = true } profiling = { workspace = true, optional = true, default-features = false } rustc-hash = { workspace = true, optional = true } # Backend: GLES glow = { workspace = true, optional = true } -cfg-if = { workspace = true, optional = true } ######################## ### Platform: Native ### @@ -318,14 +320,18 @@ khronos-egl = { workspace = true, optional = true, features = [ # Note: it's unused by emscripten, but we keep it to have single code base in egl.rs libloading = { workspace = true, optional = true } -[target.'cfg(not(target_has_atomic = "64"))'.dependencies] +[target.'cfg(any(not(target_has_atomic = "64"), not(target_has_atomic = "ptr")))'.dependencies] portable-atomic = { workspace = true, optional = true } +[target.'cfg(not(target_has_atomic = "ptr"))'.dependencies] +portable-atomic-util = { workspace = true, features = [ + "alloc", +], optional = true } + [build-dependencies] cfg_aliases.workspace = true [dev-dependencies] -cfg-if.workspace = true env_logger.workspace = true glam.workspace = true # for ray-traced-triangle example naga = { workspace = true, features = ["wgsl-in", "termcolor"] } diff --git a/wgpu-hal/build.rs b/wgpu-hal/build.rs index 960f6453008..a89db73d53c 100644 --- a/wgpu-hal/build.rs +++ b/wgpu-hal/build.rs @@ -25,6 +25,7 @@ fn main() { vulkan: { all(not(target_arch = "wasm32"), feature = "vulkan") }, // ⚠️ Keep in sync with target.cfg() definition in Cargo.toml and cfg_alias in `wgpu` crate ⚠️ static_dxc: { all(target_os = "windows", feature = "static-dxc", not(target_arch = "aarch64")) }, - supports_64bit_atomics: { target_has_atomic = "64" } + supports_64bit_atomics: { target_has_atomic = "64" }, + supports_ptr_atomics: { target_has_atomic = "ptr" } } } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 4184c8c6f1b..ae3b087b229 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -292,7 +292,7 @@ pub use dynamic::{ #[allow(unused)] use alloc::boxed::Box; -use alloc::{borrow::Cow, string::String, sync::Arc, vec::Vec}; +use alloc::{borrow::Cow, string::String, vec::Vec}; use core::{ borrow::Borrow, error::Error, @@ -306,6 +306,14 @@ use bitflags::bitflags; use thiserror::Error; use wgt::WasmNotSendSync; +cfg_if::cfg_if! { + if #[cfg(supports_ptr_atomics)] { + use alloc::sync::Arc; + } else if #[cfg(feature = "portable-atomic")] { + use portable_atomic_util::Arc; + } +} + // - Vertex + Fragment // - Compute // Task + Mesh + Fragment @@ -450,9 +458,18 @@ impl InstanceError { } #[allow(dead_code)] // may be unused on some platforms pub(crate) fn with_source(message: String, source: impl Error + Send + Sync + 'static) -> Self { + cfg_if::cfg_if! { + if #[cfg(supports_ptr_atomics)] { + let source = Arc::new(source); + } else { + // TODO(https://github.com/rust-lang/rust/issues/18598): avoid indirection via Box once arbitrary types support unsized coercion + let source: Box = Box::new(source); + let source = Arc::from(source); + } + } Self { message, - source: Some(Arc::new(source)), + source: Some(source), } } } diff --git a/wgpu-hal/src/noop/buffer.rs b/wgpu-hal/src/noop/buffer.rs index 6e9572ef8fe..9b8ab17a1fb 100644 --- a/wgpu-hal/src/noop/buffer.rs +++ b/wgpu-hal/src/noop/buffer.rs @@ -1,6 +1,14 @@ -use alloc::{sync::Arc, vec::Vec}; +use alloc::vec::Vec; use core::{cell::UnsafeCell, ops::Range, ptr}; +cfg_if::cfg_if! { + if #[cfg(supports_ptr_atomics)] { + use alloc::sync::Arc; + } else if #[cfg(feature = "portable-atomic")] { + use portable_atomic_util::Arc; + } +} + #[derive(Clone, Debug)] pub struct Buffer { /// This data is potentially accessed mutably in arbitrary non-overlapping slices, From ac4296184d3fb903a4c625a9d99a9ee197a38718 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Fri, 30 May 2025 13:47:45 +1000 Subject: [PATCH 08/11] Adjust minimal versions --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1b81fdbcb78..a08bdeba607 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,7 +159,7 @@ pico-args = { version = "0.5", features = [ ] } png = "0.17.6" pollster = "0.4" -portable-atomic = "1.2" +portable-atomic = "1.5.1" portable-atomic-util = "0.2.4" pp-rs = "0.2.1" profiling = { version = "1", default-features = false } From ae607da93548b12d8cfed54787e25eb9b592d3db Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Fri, 30 May 2025 13:50:45 +1000 Subject: [PATCH 09/11] Adjust minimal versions again --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a08bdeba607..75b1c8df90a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,7 +159,7 @@ pico-args = { version = "0.5", features = [ ] } png = "0.17.6" pollster = "0.4" -portable-atomic = "1.5.1" +portable-atomic = "1.8" portable-atomic-util = "0.2.4" pp-rs = "0.2.1" profiling = { version = "1", default-features = false } From 1b0ef889c754e88775d0b044c5a016f64f42de27 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Fri, 30 May 2025 15:13:33 +1000 Subject: [PATCH 10/11] Ensure `portable-atomic` does not appear in dependencies For atomic compatibility, users must enable `once_cell/portable-atomic` on their own. --- Cargo.lock | 3 --- naga/Cargo.toml | 2 -- wgpu-hal/Cargo.toml | 6 +----- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5616a0ba62..1102bf9b7a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2962,9 +2962,6 @@ name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -dependencies = [ - "portable-atomic", -] [[package]] name = "oorandom" diff --git a/naga/Cargo.toml b/naga/Cargo.toml index b007100d8eb..9c5c0353721 100644 --- a/naga/Cargo.toml +++ b/naga/Cargo.toml @@ -80,8 +80,6 @@ termcolor = ["codespan-reporting/termcolor"] ## Enables writing output to stderr. stderr = ["codespan-reporting/std"] -portable-atomic = ["once_cell/portable-atomic"] - [dependencies] arbitrary = { workspace = true, features = ["derive"], optional = true } arrayvec.workspace = true diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index e8dc343539d..94dc0e07e0c 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -164,11 +164,7 @@ renderdoc = ["dep:libloading", "dep:renderdoc-sys", "dep:log"] fragile-send-sync-non-atomic-wasm = [ "wgpu-types/fragile-send-sync-non-atomic-wasm", ] -portable-atomic = [ - "dep:portable-atomic", - "dep:portable-atomic-util", - "naga/portable-atomic", -] +portable-atomic = ["dep:portable-atomic", "dep:portable-atomic-util"] ################################### ### Internal Debugging Features ### From 6bc2a2a308b557bf8d723fc9a77236297eb80fc2 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Thu, 26 Jun 2025 10:01:08 +1000 Subject: [PATCH 11/11] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 930ba56a283..6511e1973a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,8 +138,6 @@ Bottom level categories: - Added initial `no_std` support to `wgpu-hal`. By @bushrat011899 in [#7599](https://github.com/gfx-rs/wgpu/pull/7599) -### Bug Fixes - ### Documentation #### General