Skip to content

MVP no_std for wgpu-core #7746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,14 @@ jobs:
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-types --no-default-features
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p naga --no-default-features
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-hal --no-default-features
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-core --no-default-features
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu --no-default-features

# Check with all compatible features
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 naga --no-default-features --features dot-out
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-hal --no-default-features --features fragile-send-sync-non-atomic-wasm
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu-core --no-default-features --features spin,once_cell,once_cell/critical-section,api_log_info,resource_log_info,strict_asserts,serde,replay,raw-window-handle,counters
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} -p wgpu --no-default-features --features serde

# Building for native platforms with standard tests.
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ Bottom level categories:
- The `destroy` functions for buffers and textures in wgpu-core are now infallible. Previously, they returned an error if called multiple times for the same object. This only affects the wgpu-core API; the wgpu API already allowed multiple `destroy` calls. By @andyleiserson in [#7686](https://github.com/gfx-rs/wgpu/pull/7686) and [#7720](https://github.com/gfx-rs/wgpu/pull/7720).
- Remove `CommandEncoder::build_acceleration_structures_unsafe_tlas` in favour of `as_hal` and apply
simplifications allowed by this. By @Vecvec in [#7513](https://github.com/gfx-rs/wgpu/pull/7513)
- Gated usage of `once_cell` and `parking_lot` in `wgpu-core` under features of the same name, enabling `no_std` support. By @bushrat011899 in [#7746](https://github.com/gfx-rs/wgpu/pull/7746).

#### Naga

Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ serde_json = "1.0.118"
serde = { version = "1.0.219", default-features = false }
shell-words = "1"
smallvec = "1.9"
# NOTE: `crossbeam-deque` currently relies on this version of spin
spin = { version = "0.9.8", default-features = false }
spirv = "0.3"
static_assertions = "1.1"
strum = { version = "0.27", default-features = false, features = ["derive"] }
Expand Down
36 changes: 31 additions & 5 deletions wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wgpu_validate_locks)'] }
# TODO(https://github.com/gfx-rs/wgpu/issues/6826): "std" is a default feature for
# compatibility with prior behavior only, and should be removed once we know how
# wgpu-core’s dependents want to handle no_std.
default = ["std"]
default = ["std", "parking_lot", "once_cell"]

#! ### Logging Configuration
# --------------------------------------------------------------------
Expand Down Expand Up @@ -117,7 +117,7 @@ fragile-send-sync-non-atomic-wasm = [

## Enable certain items to be `Send` and `Sync` when they would not otherwise be.
## Also enables backtraces in some error cases when also under cfg(debug_assertions).
std = []
std = ["once_cell?/std"]

#! ### External libraries
# --------------------------------------------------------------------
Expand All @@ -129,6 +129,25 @@ static-dxc = ["wgpu-hal/static-dxc"]
## Enable portable atomics on platforms that do not support 64bit atomics.
portable-atomic = ["dep:portable-atomic", "wgpu-hal/portable-atomic"]

## Enables the `parking_lot` set of locking primitives.
## This is the recommended implementation and will be used in preference to
## any other implementation.
## Will fallback to a `RefCell` based implementation which is `!Sync` when no
## alternative feature is enabled.
parking_lot = ["dep:parking_lot"]

## Enables the `spin` set of locking primitives.
## This is generally only useful for `no_std` targets, and will be unused if
## either `std` or `parking_lot` are available.
## Will fallback to a `RefCell` based implementation which is `!Sync` when no
## alternative feature is enabled.
spin = ["dep:spin"]

## Enables `once_cell` initialization primitives.
## This allows the `ResourcePool` to be `Sync`, but requires either `std` or
## `once_cell/critical-section` to be enabled.
once_cell = ["dep:once_cell"]

#! ### Target Conditional Features
# --------------------------------------------------------------------
# Look to wgpu-hal's Cargo.toml for explaination how these features and the wgpu-core
Expand Down Expand Up @@ -181,18 +200,25 @@ bit-vec.workspace = true
bit-set.workspace = true
bitflags.workspace = true
bytemuck = { workspace = true, optional = true }
cfg-if.workspace = true
document-features.workspace = true
hashbrown.workspace = true
indexmap.workspace = true
log.workspace = true
once_cell = { workspace = true, features = ["std"] }
parking_lot.workspace = true
once_cell = { workspace = true, optional = true }
num-traits = { workspace = true }
parking_lot = { workspace = true, optional = true }
profiling = { workspace = true, default-features = false }
raw-window-handle = { workspace = true, optional = true }
ron = { workspace = true, optional = true }
rustc-hash.workspace = true
serde = { workspace = true, features = ["default", "derive"], optional = true }
serde = { workspace = true, features = ["derive"], optional = true }
smallvec.workspace = true
spin = { workspace = true, features = [
"rwlock",
"mutex",
"spin_mutex",
], optional = true }
thiserror.workspace = true

[target.'cfg(not(target_has_atomic = "64"))'.dependencies]
Expand Down
27 changes: 14 additions & 13 deletions wgpu-core/src/lock/observing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,35 @@ use std::{
};

use super::rank::{LockRank, LockRankSet};
use super::vanilla;
use crate::FastHashSet;

/// A `Mutex` instrumented for lock acquisition order observation.
///
/// This is just a wrapper around a [`parking_lot::Mutex`], along with
/// This is just a wrapper around a [`vanilla::Mutex`], along with
/// its rank in the `wgpu_core` lock ordering.
///
/// For details, see [the module documentation][self].
pub struct Mutex<T> {
inner: parking_lot::Mutex<T>,
inner: vanilla::Mutex<T>,
rank: LockRank,
}

/// A guard produced by locking [`Mutex`].
///
/// This is just a wrapper around a [`parking_lot::MutexGuard`], along
/// This is just a wrapper around a [`vanilla::MutexGuard`], along
/// with the state needed to track lock acquisition.
///
/// For details, see [the module documentation][self].
pub struct MutexGuard<'a, T> {
inner: parking_lot::MutexGuard<'a, T>,
inner: vanilla::MutexGuard<'a, T>,
_state: LockStateGuard,
}

impl<T> Mutex<T> {
pub fn new(rank: LockRank, value: T) -> Mutex<T> {
Mutex {
inner: parking_lot::Mutex::new(value),
inner: vanilla::Mutex::new(rank, value),
rank,
}
}
Expand Down Expand Up @@ -104,41 +105,41 @@ impl<T: core::fmt::Debug> core::fmt::Debug for Mutex<T> {

/// An `RwLock` instrumented for lock acquisition order observation.
///
/// This is just a wrapper around a [`parking_lot::RwLock`], along with
/// This is just a wrapper around a [`vanilla::RwLock`], along with
/// its rank in the `wgpu_core` lock ordering.
///
/// For details, see [the module documentation][self].
pub struct RwLock<T> {
inner: parking_lot::RwLock<T>,
inner: vanilla::RwLock<T>,
rank: LockRank,
}

/// A read guard produced by locking [`RwLock`] for reading.
///
/// This is just a wrapper around a [`parking_lot::RwLockReadGuard`], along with
/// This is just a wrapper around a [`vanilla::RwLockReadGuard`], along with
/// the state needed to track lock acquisition.
///
/// For details, see [the module documentation][self].
pub struct RwLockReadGuard<'a, T> {
inner: parking_lot::RwLockReadGuard<'a, T>,
inner: vanilla::RwLockReadGuard<'a, T>,
_state: LockStateGuard,
}

/// A write guard produced by locking [`RwLock`] for writing.
///
/// This is just a wrapper around a [`parking_lot::RwLockWriteGuard`], along
/// This is just a wrapper around a [`vanilla::RwLockWriteGuard`], along
/// with the state needed to track lock acquisition.
///
/// For details, see [the module documentation][self].
pub struct RwLockWriteGuard<'a, T> {
inner: parking_lot::RwLockWriteGuard<'a, T>,
inner: vanilla::RwLockWriteGuard<'a, T>,
_state: LockStateGuard,
}

impl<T> RwLock<T> {
pub fn new(rank: LockRank, value: T) -> RwLock<T> {
RwLock {
inner: parking_lot::RwLock::new(value),
inner: vanilla::RwLock::new(rank, value),
rank,
}
}
Expand All @@ -165,7 +166,7 @@ impl<T> RwLock<T> {
impl<'a, T> RwLockWriteGuard<'a, T> {
pub fn downgrade(this: Self) -> RwLockReadGuard<'a, T> {
RwLockReadGuard {
inner: parking_lot::RwLockWriteGuard::downgrade(this.inner),
inner: vanilla::RwLockWriteGuard::downgrade(this.inner),
_state: this._state,
}
}
Expand Down
27 changes: 14 additions & 13 deletions wgpu-core/src/lock/ranked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,27 @@
use core::{cell::Cell, fmt, ops, panic::Location};

use super::rank::LockRank;
use super::vanilla;

/// A `Mutex` instrumented for deadlock prevention.
///
/// This is just a wrapper around a [`parking_lot::Mutex`], along with
/// This is just a wrapper around a [`vanilla::Mutex`], along with
/// its rank in the `wgpu_core` lock ordering.
///
/// For details, see [the module documentation][self].
pub struct Mutex<T> {
inner: parking_lot::Mutex<T>,
inner: vanilla::Mutex<T>,
rank: LockRank,
}

/// A guard produced by locking [`Mutex`].
///
/// This is just a wrapper around a [`parking_lot::MutexGuard`], along
/// This is just a wrapper around a [`vanilla::MutexGuard`], along
/// with the state needed to track lock acquisition.
///
/// For details, see [the module documentation][self].
pub struct MutexGuard<'a, T> {
inner: parking_lot::MutexGuard<'a, T>,
inner: vanilla::MutexGuard<'a, T>,
saved: LockStateGuard,
}

Expand Down Expand Up @@ -177,7 +178,7 @@ fn release(saved: LockState) {
impl<T> Mutex<T> {
pub fn new(rank: LockRank, value: T) -> Mutex<T> {
Mutex {
inner: parking_lot::Mutex::new(value),
inner: vanilla::Mutex::new(rank, value),
rank,
}
}
Expand Down Expand Up @@ -214,41 +215,41 @@ impl<T: fmt::Debug> fmt::Debug for Mutex<T> {

/// An `RwLock` instrumented for deadlock prevention.
///
/// This is just a wrapper around a [`parking_lot::RwLock`], along with
/// This is just a wrapper around a [`vanilla::RwLock`], along with
/// its rank in the `wgpu_core` lock ordering.
///
/// For details, see [the module documentation][self].
pub struct RwLock<T> {
inner: parking_lot::RwLock<T>,
inner: vanilla::RwLock<T>,
rank: LockRank,
}

/// A read guard produced by locking [`RwLock`] for reading.
///
/// This is just a wrapper around a [`parking_lot::RwLockReadGuard`], along with
/// This is just a wrapper around a [`vanilla::RwLockReadGuard`], along with
/// the state needed to track lock acquisition.
///
/// For details, see [the module documentation][self].
pub struct RwLockReadGuard<'a, T> {
inner: parking_lot::RwLockReadGuard<'a, T>,
inner: vanilla::RwLockReadGuard<'a, T>,
saved: LockStateGuard,
}

/// A write guard produced by locking [`RwLock`] for writing.
///
/// This is just a wrapper around a [`parking_lot::RwLockWriteGuard`], along
/// This is just a wrapper around a [`vanilla::RwLockWriteGuard`], along
/// with the state needed to track lock acquisition.
///
/// For details, see [the module documentation][self].
pub struct RwLockWriteGuard<'a, T> {
inner: parking_lot::RwLockWriteGuard<'a, T>,
inner: vanilla::RwLockWriteGuard<'a, T>,
saved: LockStateGuard,
}

impl<T> RwLock<T> {
pub fn new(rank: LockRank, value: T) -> RwLock<T> {
RwLock {
inner: parking_lot::RwLock::new(value),
inner: vanilla::RwLock::new(rank, value),
rank,
}
}
Expand All @@ -275,7 +276,7 @@ impl<T> RwLock<T> {
impl<'a, T> RwLockWriteGuard<'a, T> {
pub fn downgrade(this: Self) -> RwLockReadGuard<'a, T> {
RwLockReadGuard {
inner: parking_lot::RwLockWriteGuard::downgrade(this.inner),
inner: vanilla::RwLockWriteGuard::downgrade(this.inner),
saved: this.saved,
}
}
Expand Down
Loading
Loading