diff --git a/Cargo.lock b/Cargo.lock index 2eb5cdfe71..c417ac4aa8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5015,6 +5015,7 @@ dependencies = [ "ordered-float 5.0.0", "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 e9f0254aed..52ef517577 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,7 +159,8 @@ pico-args = { version = "0.5", features = [ ] } png = "0.17.6" pollster = "0.4" -portable-atomic = "1.2" +portable-atomic = "1.8" +portable-atomic-util = "0.2.4" pp-rs = "0.2.1" profiling = { version = "1", default-features = false } quote = "1.0.38" diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 07c52ddadb..94dc0e07e0 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,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"] +portable-atomic = ["dep:portable-atomic", "dep:portable-atomic-util"] ################################### ### Internal Debugging Features ### @@ -207,6 +206,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 +216,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 +316,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 960f645300..a89db73d53 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 82a5af8d42..c5d81b2860 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 6e9572ef8f..9b8ab17a1f 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,