Skip to content

Commit 673e4ec

Browse files
Add no_std support (#265)
`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.0", default-features = false, features = ["hashbrown", "other features"] } ``` Co-authored-by: Marijn Suijten <[email protected]>
1 parent 69730b7 commit 673e4ec

File tree

14 files changed

+313
-112
lines changed

14 files changed

+313
-112
lines changed

.github/workflows/ci.yml

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,56 @@ name: CI
44

55
jobs:
66
check_msrv:
7-
name: Check MSRV (1.71.0)
7+
name: Check MSRV
88
strategy:
99
matrix:
10-
include:
10+
target:
1111
- os: ubuntu-latest
12-
features: vulkan
12+
backend: vulkan
1313
- os: windows-latest
14-
features: vulkan,d3d12
14+
backend: vulkan,d3d12
1515
- os: macos-latest
16-
features: vulkan,metal
17-
runs-on: ${{ matrix.os }}
16+
backend: vulkan,metal
17+
version:
18+
- msrv: 1.71.0
19+
features: std
20+
- msrv: 1.81.0
21+
features: hashbrown
22+
runs-on: ${{ matrix.target.os }}
1823
steps:
1924
- uses: actions/checkout@v4
2025
- uses: dtolnay/rust-toolchain@nightly
2126
- name: Generate lockfile with minimal dependency versions
2227
run: cargo +nightly generate-lockfile -Zminimal-versions
23-
- uses: dtolnay/[email protected]
24-
# Note that examples are extempt from the MSRV check, so that they can use newer Rust features
25-
- run: cargo check --workspace --features ${{ matrix.features }} --no-default-features
28+
- uses: dtolnay/rust-toolchain@master
29+
with:
30+
toolchain: ${{ matrix.version.msrv }}
31+
# Note that examples are exempt from the MSRV check, so that they can use newer Rust features
32+
- run: cargo check --workspace --no-default-features --features ${{ matrix.target.backend }},${{ matrix.version.features }}
2633

2734
test:
2835
name: Test Suite
2936
strategy:
3037
matrix:
31-
include:
38+
target:
3239
- os: ubuntu-latest
33-
features: vulkan,visualizer
40+
backend: vulkan
3441
- os: windows-latest
35-
features: vulkan,visualizer,d3d12
42+
backend: vulkan,d3d12
3643
- os: macos-latest
37-
features: vulkan,visualizer,metal
38-
runs-on: ${{ matrix.os }}
44+
backend: vulkan,metal
45+
features:
46+
- hashbrown
47+
- std
48+
- hashbrown,std
49+
- visualizer,std
50+
runs-on: ${{ matrix.target.os }}
3951
steps:
4052
- uses: actions/checkout@v4
4153
- name: Cargo test all targets
42-
run: cargo test --workspace --all-targets --features ${{ matrix.features }} --no-default-features
54+
run: cargo test --workspace --all-targets --no-default-features --features ${{ matrix.target.backend }},${{ matrix.features }}
4355
- name: Cargo test docs
44-
run: cargo test --workspace --doc --features ${{ matrix.features }} --no-default-features
56+
run: cargo test --workspace --doc --no-default-features --features ${{ matrix.target.backend }},${{ matrix.features }}
4557

4658
fmt:
4759
name: Rustfmt
@@ -55,18 +67,23 @@ jobs:
5567
name: Clippy
5668
strategy:
5769
matrix:
58-
include:
70+
target:
5971
- os: ubuntu-latest
60-
features: vulkan,visualizer
72+
backend: vulkan
6173
- os: windows-latest
62-
features: vulkan,visualizer,d3d12
74+
backend: vulkan,d3d12
6375
- os: macos-latest
64-
features: vulkan,visualizer,metal
65-
runs-on: ${{ matrix.os }}
76+
backend: vulkan,metal
77+
features:
78+
- hashbrown
79+
- std
80+
- hashbrown,std
81+
- visualizer,std
82+
runs-on: ${{ matrix.target.os }}
6683
steps:
6784
- uses: actions/checkout@v4
6885
- name: Cargo clippy
69-
run: cargo clippy --workspace --all-targets --features ${{ matrix.features }} --no-default-features -- -D warnings
86+
run: cargo clippy --workspace --all-targets --no-default-features --features ${{ matrix.target.backend }},${{ matrix.features }} -- -D warnings
7087

7188
doc:
7289
name: Build documentation

Cargo.toml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@ include = [
2323
all-features = true
2424

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

3637
[target.'cfg(target_vendor = "apple")'.dependencies]
3738
objc2 = { version = "0.6", default-features = false, optional = true }
@@ -88,9 +89,12 @@ name = "metal-buffer"
8889
required-features = ["metal"]
8990

9091
[features]
92+
std = ["presser/std"]
9193
visualizer = ["dep:egui", "dep:egui_extras"]
9294
vulkan = ["dep:ash"]
9395
d3d12 = ["dep:windows"]
9496
metal = ["dep:objc2", "dep:objc2-metal", "dep:objc2-foundation"]
97+
# Enables the FreeListAllocator when `std` is not enabled by using the `hashbrown` crate
98+
hashbrown = ["dep:hashbrown"]
9599

96-
default = ["d3d12", "vulkan", "metal"]
100+
default = ["std", "d3d12", "vulkan", "metal"]

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ let mut allocator = Allocator::new(&AllocatorCreateDesc {
136136
```
137137

138138
## Simple Metal allocation example
139+
139140
```rust
140141
use gpu_allocator::metal::*;
141142
use gpu_allocator::MemoryLocation;
@@ -161,9 +162,36 @@ drop(resource);
161162
allocator.free(&allocation).unwrap();
162163
```
163164

165+
## `no_std` support
166+
167+
`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:
168+
169+
```toml
170+
[dependencies]
171+
gpu-allocator = { version = "0.27.0", default-features = false, features = ["hashbrown", "other features"] }
172+
```
173+
174+
To support both `std` and `no_std` builds in your project, use the following in your `Cargo.toml`:
175+
176+
```toml
177+
[features]
178+
default = ["std", "other features"]
179+
180+
std = ["gpu-allocator/std"]
181+
hashbrown = ["gpu-allocator/hashbrown"]
182+
other_features = []
183+
184+
[dependencies]
185+
gpu-allocator = { version = "0.27.0", default-features = false }
186+
```
187+
164188
## Minimum Supported Rust Version
165189

166-
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.
190+
The MSRV for this crate and the `vulkan`, `d3d12` and `metal` features is Rust **1.71**.
191+
192+
The `no_std` support requires Rust **1.81** or higher because `no_std` support of dependency `thiserror` requires `core::error::Error` which is stabilized in **1.81**.
193+
194+
Any other features such as the `visualizer` (with all the `egui` dependencies) may have a higher requirement and are not tested in our CI.
167195

168196
## License
169197

README.tpl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,36 @@ gpu-allocator = "0.27.0"
1919

2020
{{readme}}
2121

22+
## `no_std` support
23+
24+
`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:
25+
26+
```toml
27+
[dependencies]
28+
gpu-allocator = { version = "0.27.0", default-features = false, features = ["hashbrown", "other features"] }
29+
```
30+
31+
To support both `std` and `no_std` builds in your project, use the following in your `Cargo.toml`:
32+
33+
```toml
34+
[features]
35+
default = ["std", "other features"]
36+
37+
std = ["gpu-allocator/std"]
38+
hashbrown = ["gpu-allocator/hashbrown"]
39+
other_features = []
40+
41+
[dependencies]
42+
gpu-allocator = { version = "0.27.0", default-features = false }
43+
```
44+
2245
## Minimum Supported Rust Version
2346

24-
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.
47+
The MSRV for this crate and the `vulkan`, `d3d12` and `metal` features is Rust **1.71**.
48+
49+
The `no_std` support requires Rust **1.81** or higher because `no_std` support of dependency `thiserror` requires `core::error::Error` which is stabilized in **1.81**.
50+
51+
Any other features such as the `visualizer` (with all the `egui` dependencies) may have a higher requirement and are not tested in our CI.
2552

2653
## License
2754

release.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ sign-tag = true
66
publish = false
77

88
pre-release-replacements = [
9-
{ file = "README.md", search = "gpu-allocator = .*", replace = "{{crate_name}} = \"{{version}}\"" },
10-
{ file = "README.tpl", search = "gpu-allocator = .*", replace = "{{crate_name}} = \"{{version}}\"" },
9+
{ file = "README.md", search = "gpu-allocator = \".*\"", replace = "{{crate_name}} = \"{{version}}\"" },
10+
{ file = "README.tpl", search = "gpu-allocator = \".*\"", replace = "{{crate_name}} = \"{{version}}\"" },
11+
{ file = "README.md", search = "gpu-allocator = \\{ version = \".*?\"", replace = "{{crate_name}} = { version = \"{{version}}\"" },
12+
{ file = "README.tpl", search = "gpu-allocator = \\{ version = \".*?\"", replace = "{{crate_name}} = { version = \"{{version}}\"" },
1113
]

src/allocator/dedicated_block_allocator/mod.rs

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
#![deny(unsafe_code, clippy::unwrap_used)]
2+
#[cfg(feature = "std")]
3+
use alloc::sync::Arc;
4+
use alloc::{
5+
borrow::ToOwned,
6+
string::{String, ToString},
7+
vec::Vec,
8+
};
9+
#[cfg(feature = "std")]
10+
use std::backtrace::Backtrace;
11+
12+
use log::{log, Level};
213

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

6-
use std::{backtrace::Backtrace, sync::Arc};
7-
8-
use log::{log, Level};
9-
1017
use super::{AllocationReport, AllocationType, SubAllocator, SubAllocatorBase};
1118
use crate::{AllocationError, Result};
1219

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

@@ -25,6 +33,7 @@ impl DedicatedBlockAllocator {
2533
size,
2634
allocated: 0,
2735
name: None,
36+
#[cfg(feature = "std")]
2837
backtrace: Arc::new(Backtrace::disabled()),
2938
}
3039
}
@@ -39,8 +48,8 @@ impl SubAllocator for DedicatedBlockAllocator {
3948
_allocation_type: AllocationType,
4049
_granularity: u64,
4150
name: &str,
42-
backtrace: Arc<Backtrace>,
43-
) -> Result<(u64, std::num::NonZeroU64)> {
51+
#[cfg(feature = "std")] backtrace: Arc<Backtrace>,
52+
) -> Result<(u64, core::num::NonZeroU64)> {
4453
if self.allocated != 0 {
4554
return Err(AllocationError::OutOfMemory);
4655
}
@@ -53,15 +62,18 @@ impl SubAllocator for DedicatedBlockAllocator {
5362

5463
self.allocated = size;
5564
self.name = Some(name.to_string());
56-
self.backtrace = backtrace;
65+
#[cfg(feature = "std")]
66+
{
67+
self.backtrace = backtrace;
68+
}
5769

5870
#[allow(clippy::unwrap_used)]
59-
let dummy_id = std::num::NonZeroU64::new(1).unwrap();
71+
let dummy_id = core::num::NonZeroU64::new(1).unwrap();
6072
Ok((0, dummy_id))
6173
}
6274

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

7284
fn rename_allocation(
7385
&mut self,
74-
chunk_id: Option<std::num::NonZeroU64>,
86+
chunk_id: Option<core::num::NonZeroU64>,
7587
name: &str,
7688
) -> Result<()> {
77-
if chunk_id != std::num::NonZeroU64::new(1) {
89+
if chunk_id != core::num::NonZeroU64::new(1) {
7890
Err(AllocationError::Internal("Chunk ID must be 1.".into()))
7991
} else {
8092
self.name = Some(name.into());
@@ -90,6 +102,20 @@ impl SubAllocator for DedicatedBlockAllocator {
90102
) {
91103
let empty = "".to_string();
92104
let name = self.name.as_ref().unwrap_or(&empty);
105+
let backtrace_info;
106+
#[cfg(feature = "std")]
107+
{
108+
// TODO: Allocation could be avoided here if https://github.com/rust-lang/rust/pull/139135 is merged and stabilized.
109+
backtrace_info = format!(
110+
",
111+
backtrace: {}",
112+
self.backtrace
113+
)
114+
}
115+
#[cfg(not(feature = "std"))]
116+
{
117+
backtrace_info = ""
118+
}
93119

94120
log!(
95121
log_level,
@@ -98,16 +124,14 @@ impl SubAllocator for DedicatedBlockAllocator {
98124
memory block: {}
99125
dedicated allocation: {{
100126
size: 0x{:x},
101-
name: {},
102-
backtrace: {}
127+
name: {}{backtrace_info}
103128
}}
104129
}}"#,
105130
memory_type_index,
106131
memory_block_index,
107132
self.size,
108133
name,
109-
self.backtrace
110-
)
134+
);
111135
}
112136

113137
fn report_allocations(&self) -> Vec<AllocationReport> {

0 commit comments

Comments
 (0)