Skip to content
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

Add no_std support #265

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fbc57a3
add `default-feature = false` to some deps, `std` feature and `hashbr…
CrazyboyQCD Feb 12, 2025
8f853b0
add `no_std` feature compile error
CrazyboyQCD Feb 12, 2025
e3ca7fb
remove `std::backtrace::Backtrace` in `no_std`
CrazyboyQCD Feb 12, 2025
eb9e04c
replace `std::*` with `core::*` or `alloc::*`
CrazyboyQCD Feb 12, 2025
48be63c
add clippy lints for `no_std` maintenance
CrazyboyQCD Feb 13, 2025
4d7b668
revert formatting of `Cargo.toml`
CrazyboyQCD Feb 13, 2025
3cee15f
fix typos in deps
CrazyboyQCD Feb 13, 2025
51e8723
add non_exhaustive for `AllocatorDebugSettings` for backward compatible
CrazyboyQCD Feb 13, 2025
a4d3463
reorder imports and mods
CrazyboyQCD Feb 13, 2025
d1caf98
format backtrace ahead by feature instead of duplicated log statements
CrazyboyQCD Feb 13, 2025
4c45a01
reorder mod in allocator module
CrazyboyQCD Feb 13, 2025
f2a6bfb
make `std` feature conflict with `hashbrown` in compile error and gat…
CrazyboyQCD Feb 13, 2025
d59fe26
restore trailing comma
CrazyboyQCD Feb 27, 2025
3e00364
remove empty line and reorder import
CrazyboyQCD Feb 27, 2025
457411a
simplify memory leak logging
CrazyboyQCD Feb 27, 2025
578ada0
prefer using `hashbrown`'s collections when `std` and `hashbrown` are…
CrazyboyQCD Feb 27, 2025
39abe59
update `CI` for `std` environment
CrazyboyQCD Feb 27, 2025
742a2ce
document the `hashbrown` feature in `Cargo.toml`
CrazyboyQCD Apr 1, 2025
694b6ff
update `CI` with `no_std`
CrazyboyQCD Apr 1, 2025
3e453ed
emit compile error when none of `std` and `hashbrown` is enabled
CrazyboyQCD Apr 1, 2025
541e814
CI: Simplify and complete `matrix` setup
MarijnS95 Apr 1, 2025
4123593
update missed `std` usages
CrazyboyQCD Apr 2, 2025
3d962a4
keep style of compile error the same
CrazyboyQCD Apr 2, 2025
66dbf08
add todo related with storing of `format_args!` outside `format!`
CrazyboyQCD Apr 2, 2025
10d0742
update missed `std` usages
CrazyboyQCD Apr 2, 2025
0ab0c88
fix lint
CrazyboyQCD Apr 2, 2025
e896fab
update `CI`
CrazyboyQCD Apr 2, 2025
8bdedba
fix lint
CrazyboyQCD Apr 2, 2025
c4da9ba
add `no_std` content in `README`
CrazyboyQCD Apr 3, 2025
d73de57
fix `CI`
CrazyboyQCD Apr 3, 2025
d27a627
Merge branch 'main' into no-std-support
CrazyboyQCD Apr 3, 2025
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
48 changes: 29 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,48 @@ jobs:
name: Check MSRV (1.71.0)
strategy:
matrix:
include:
target:
- os: ubuntu-latest
features: vulkan
backend: vulkan
- os: windows-latest
features: vulkan,d3d12
backend: vulkan,d3d12
- os: macos-latest
features: vulkan,metal
runs-on: ${{ matrix.os }}
backend: vulkan,metal
features:
- hashbrown
- std
- hashbrown,std
runs-on: ${{ matrix.target.os }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- name: Generate lockfile with minimal dependency versions
run: cargo +nightly generate-lockfile -Zminimal-versions
- uses: dtolnay/[email protected]
# Note that examples are extempt from the MSRV check, so that they can use newer Rust features
- run: cargo check --workspace --features ${{ matrix.features }} --no-default-features
- run: cargo check --workspace --features ${{ matrix.target.backend }},${{ matrix.features }} --no-default-features

test:
name: Test Suite
strategy:
matrix:
include:
target:
- os: ubuntu-latest
features: vulkan,visualizer
backend: vulkan
- os: windows-latest
features: vulkan,visualizer,d3d12,public-winapi
backend: vulkan,d3d12
- os: macos-latest
features: vulkan,visualizer,metal
runs-on: ${{ matrix.os }}
backend: vulkan,metal
features:
- std
- hashbrown,std
runs-on: ${{ matrix.target.os }}
steps:
- uses: actions/checkout@v4
- name: Cargo test all targets
run: cargo test --workspace --all-targets --features ${{ matrix.features }} --no-default-features
run: cargo test --workspace --all-targets --features visualizer,${{ matrix.target.backend }},${{ matrix.features }} --no-default-features
- name: Cargo test docs
run: cargo test --workspace --doc --features ${{ matrix.features }} --no-default-features
run: cargo test --workspace --doc --features visualizer,${{ matrix.target.backend }},${{ matrix.features }} --no-default-features

fmt:
name: Rustfmt
Expand All @@ -55,18 +62,21 @@ jobs:
name: Clippy
strategy:
matrix:
include:
target:
- os: ubuntu-latest
features: vulkan,visualizer
backend: vulkan
- os: windows-latest
features: vulkan,visualizer,d3d12,public-winapi
backend: vulkan,d3d12
- os: macos-latest
features: vulkan,visualizer,metal
runs-on: ${{ matrix.os }}
backend: vulkan,metal
features:
- std
- hashbrown,std
runs-on: ${{ matrix.target.os }}
steps:
- uses: actions/checkout@v4
- name: Cargo clippy
run: cargo clippy --workspace --all-targets --features ${{ matrix.features }} --no-default-features -- -D warnings
run: cargo clippy --workspace --all-targets --features visualizer,${{ matrix.target.backend }},${{ matrix.features }} --no-default-features -- -D warnings

doc:
name: Build documentation
Expand Down
12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ include = [
all-features = true

[dependencies]
log = "0.4"
thiserror = "1.0"
presser = { version = "0.3" }
log = { version = "0.4", default-features = false }
thiserror = { version = "2.0", default-features = false }
presser = { version = "0.3", default-features = false }
# Only needed for Vulkan. Disable all default features as good practice,
# such as the ability to link/load a Vulkan library.
ash = { version = "0.38", optional = true, default-features = false, features = ["debug"] }
# Only needed for visualizer.
egui = { version = ">=0.24, <=0.27", optional = true, default-features = false }
egui_extras = { version = ">=0.24, <=0.27", optional = true, default-features = false }
hashbrown = { version = "0.15.2", optional = true }

[target.'cfg(target_vendor = "apple")'.dependencies]
objc2 = { version = "0.6", default-features = false, optional = true }
Expand Down Expand Up @@ -98,11 +99,14 @@ name = "metal-buffer"
required-features = ["metal"]

[features]
std = ["presser/std"]
visualizer = ["dep:egui", "dep:egui_extras"]
vulkan = ["dep:ash"]
d3d12 = ["dep:windows"]
metal = ["dep:objc2", "dep:objc2-metal", "dep:objc2-foundation"]
# Expose helper functionality for winapi types to interface with gpu-allocator, which is primarily windows-rs driven
public-winapi = ["dep:winapi"]
# Enables the FreeListAllocator when `std` is not enabled by using the `hashbrown` crate
hashbrown = ["dep:hashbrown"]

default = ["d3d12", "vulkan", "metal"]
default = ["std", "d3d12", "vulkan", "metal"]
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ let mut allocator = Allocator::new(&AllocatorCreateDesc {
```

## Simple Metal allocation example

```rust
use gpu_allocator::metal::*;
use gpu_allocator::MemoryLocation;
Expand All @@ -167,9 +168,39 @@ drop(resource);
allocator.free(&allocation).unwrap();
```

## `no_std` Support

`no_std` support can be enabled by compiling with `--no-default-features` to
disable `std` support and `--features hashbrown` for `Hash` collections that are only
defined in `std` for internal usages in crate. For example:

```toml
[dependencies]
gpu-allocator = { version = "0.27", default-features = false, features = ["hashbrown", "other features"] }
```

To support both `std` and `no_std` builds in project, you can use the following
in your `Cargo.toml`:

```toml
[features]
default = ["std", "other features"]

std = ["gpu-allocator/std"]
hashbrown = ["gpu-allocator/hashbrown"]
other_features = []

[dependencies]
gpu-allocator = { version = "0.27", default-features = false }
```

## Minimum Supported Rust Version

The MSRV for this crate and the `vulkan`, `d3d12` and `metal` features is Rust 1.71. Any other features such as the `visualizer` (with all the `egui` dependencies) may have a higher requirement and are not tested in our CI.
The MSRV for this crate and the `vulkan`, `d3d12` and `metal` features is Rust **1.71**.

The `no_std` support requires version above **1.81** beacuase `no_std` support of dependency `thiserror` requires `core::error::Error` which is stabalized in **1.81**.

Any other features such as the `visualizer` (with all the `egui` dependencies) may have a higher requirement and are not tested in our CI.

## License

Expand Down
32 changes: 31 additions & 1 deletion README.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,39 @@ gpu-allocator = "0.27.0"

{{readme}}

## `no_std` Support

`no_std` support can be enabled by compiling with `--no-default-features` to
disable `std` support and `--features hashbrown` for `Hash` collections that are only
defined in `std` for internal usages in crate. For example:

```toml
[dependencies]
gpu-allocator = { version = "0.27", default-features = false, features = ["hashbrown", "other features"] }
```

To support both `std` and `no_std` builds in project, you can use the following
in your `Cargo.toml`:

```toml
[features]
default = ["std", "other features"]

std = ["gpu-allocator/std"]
hashbrown = ["gpu-allocator/hashbrown"]
other_features = []

[dependencies]
gpu-allocator = { version = "0.27", default-features = false }
```

## Minimum Supported Rust Version

The MSRV for this crate and the `vulkan`, `d3d12` and `metal` features is Rust 1.71. Any other features such as the `visualizer` (with all the `egui` dependencies) may have a higher requirement and are not tested in our CI.
The MSRV for this crate and the `vulkan`, `d3d12` and `metal` features is Rust **1.71**.

The `no_std` support requires version above **1.81** beacuase `no_std` support of dependency `thiserror` requires `core::error::Error` which is stabalized in **1.81**.

Any other features such as the `visualizer` (with all the `egui` dependencies) may have a higher requirement and are not tested in our CI.

## License

Expand Down
56 changes: 40 additions & 16 deletions src/allocator/dedicated_block_allocator/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
#![deny(unsafe_code, clippy::unwrap_used)]
#[cfg(feature = "std")]
use alloc::sync::Arc;
use alloc::{
borrow::ToOwned,
string::{String, ToString},
vec::Vec,
};
#[cfg(feature = "std")]
use std::backtrace::Backtrace;

use log::{log, Level};

#[cfg(feature = "visualizer")]
pub(crate) mod visualizer;

use std::{backtrace::Backtrace, sync::Arc};

use log::{log, Level};

use super::{AllocationReport, AllocationType, SubAllocator, SubAllocatorBase};
use crate::{AllocationError, Result};

Expand All @@ -16,6 +23,7 @@ pub(crate) struct DedicatedBlockAllocator {
allocated: u64,
/// Only used if [`crate::AllocatorDebugSettings::store_stack_traces`] is [`true`]
name: Option<String>,
#[cfg(feature = "std")]
backtrace: Arc<Backtrace>,
}

Expand All @@ -25,6 +33,7 @@ impl DedicatedBlockAllocator {
size,
allocated: 0,
name: None,
#[cfg(feature = "std")]
backtrace: Arc::new(Backtrace::disabled()),
}
}
Expand All @@ -39,8 +48,8 @@ impl SubAllocator for DedicatedBlockAllocator {
_allocation_type: AllocationType,
_granularity: u64,
name: &str,
backtrace: Arc<Backtrace>,
) -> Result<(u64, std::num::NonZeroU64)> {
#[cfg(feature = "std")] backtrace: Arc<Backtrace>,
) -> Result<(u64, core::num::NonZeroU64)> {
if self.allocated != 0 {
return Err(AllocationError::OutOfMemory);
}
Expand All @@ -53,15 +62,18 @@ impl SubAllocator for DedicatedBlockAllocator {

self.allocated = size;
self.name = Some(name.to_string());
self.backtrace = backtrace;
#[cfg(feature = "std")]
{
self.backtrace = backtrace;
}

#[allow(clippy::unwrap_used)]
let dummy_id = std::num::NonZeroU64::new(1).unwrap();
let dummy_id = core::num::NonZeroU64::new(1).unwrap();
Ok((0, dummy_id))
}

fn free(&mut self, chunk_id: Option<std::num::NonZeroU64>) -> Result<()> {
if chunk_id != std::num::NonZeroU64::new(1) {
fn free(&mut self, chunk_id: Option<core::num::NonZeroU64>) -> Result<()> {
if chunk_id != core::num::NonZeroU64::new(1) {
Err(AllocationError::Internal("Chunk ID must be 1.".into()))
} else {
self.allocated = 0;
Expand All @@ -71,10 +83,10 @@ impl SubAllocator for DedicatedBlockAllocator {

fn rename_allocation(
&mut self,
chunk_id: Option<std::num::NonZeroU64>,
chunk_id: Option<core::num::NonZeroU64>,
name: &str,
) -> Result<()> {
if chunk_id != std::num::NonZeroU64::new(1) {
if chunk_id != core::num::NonZeroU64::new(1) {
Err(AllocationError::Internal("Chunk ID must be 1.".into()))
} else {
self.name = Some(name.into());
Expand All @@ -90,6 +102,20 @@ impl SubAllocator for DedicatedBlockAllocator {
) {
let empty = "".to_string();
let name = self.name.as_ref().unwrap_or(&empty);
let backtrace_info;
#[cfg(feature = "std")]
{
// TODO: Allocation could be avoided here if https://github.com/rust-lang/rust/pull/139135 is merged and stabilized.
backtrace_info = format!(
",
backtrace: {}",
self.backtrace
)
}
#[cfg(not(feature = "std"))]
{
backtrace_info = ""
}

log!(
log_level,
Expand All @@ -98,16 +124,14 @@ impl SubAllocator for DedicatedBlockAllocator {
memory block: {}
dedicated allocation: {{
size: 0x{:x},
name: {},
backtrace: {}
name: {}{backtrace_info}
}}
}}"#,
memory_type_index,
memory_block_index,
self.size,
name,
self.backtrace
)
);
}

fn report_allocations(&self) -> Vec<AllocationReport> {
Expand Down
Loading