Skip to content

Commit df54acc

Browse files
use hashbrown in more crates (etc.) (#6938)
Co-authored-by: Connor Fitzgerald <[email protected]>
1 parent fcbadc9 commit df54acc

File tree

28 files changed

+96
-60
lines changed

28 files changed

+96
-60
lines changed

CHANGELOG.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,16 @@ Bottom level categories:
5050

5151
#### General
5252

53+
- Use `hashbrown` to simplify no-std support. By Brody in [#6938](https://github.com/gfx-rs/wgpu/pull/6938) & [#6925](https://github.com/gfx-rs/wgpu/pull/6925).
5354
- If you use Binding Arrays in a bind group, you may not use Dynamic Offset Buffers or Uniform Buffers in that bind group. By @cwfitzgerald in [#6811](https://github.com/gfx-rs/wgpu/pull/6811)
5455

56+
5557
##### Refactored internal trace path parameter
5658

5759
Refactored some functions to handle the internal trace path as a string to avoid possible issues with `no_std` support.
5860

5961
By @brodycj in [#6924](https://github.com/gfx-rs/wgpu/pull/6924).
6062

61-
##### Start using `hashbrown`
62-
63-
Use `hashbrown` in `wgpu-core`, `wgpu-hal` & `wgpu-info` to simplify no-std support. (This may help improve performance as well.)
64-
65-
By @brodycj in [#6925](https://github.com/gfx-rs/wgpu/pull/6925).
66-
6763
#### Vulkan
6864

6965
##### HAL queue callback support

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ default-members = [
4545
[workspace.lints.clippy]
4646
manual_c_str_literals = "allow"
4747
ref_as_ptr = "warn"
48+
# NOTE: disallowed-types is configured in other file: clippy.toml
4849

4950
[workspace.package]
5051
edition = "2021"
@@ -126,9 +127,11 @@ raw-window-handle = "0.6"
126127
rayon = "1"
127128
renderdoc-sys = "1.1.0"
128129
ron = "0.8"
129-
# rustc-hash 2.0 is a completely different hasher with different performance characteristics
130+
# NOTE: rustc-hash v2 is a completely different hasher with different performance characteristics
131+
# see discussion here (including with some other alternatives): https://github.com/gfx-rs/wgpu/issues/6999
132+
# (using default-features = false to support no-std build, avoiding any extra features that may require std::collections)
133+
rustc-hash = { version = "1", default-features = false }
130134
serde_json = "1.0.137"
131-
rustc-hash = "1"
132135
serde = { version = "1", default-features = false }
133136
smallvec = "1"
134137
static_assertions = "1.1.0"

clippy.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# NOTE: Other global Clippy config is in top-level Cargo.toml.
2+
3+
disallowed-types = [
4+
{ path = "std::collections::HashMap", reason = "use hashbrown::HashMap instead" },
5+
{ path = "std::collections::HashSet", reason = "use hashbrown::HashSet instead" },
6+
{ path = "rustc_hash::FxHashMap", reason = "use hashbrown::HashMap instead" },
7+
{ path = "rustc_hash::FxHashSet", reason = "use hashbrown::HashSet instead" },
8+
]

deno_webgpu/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ wgpu-core = { workspace = true, features = [
2828
wgpu-types = { workspace = true, features = ["serde"] }
2929

3030
deno_core.workspace = true
31+
hashbrown = { workspace = true, features = ["serde"] }
3132
raw-window-handle = { workspace = true }
3233
serde = { workspace = true, features = ["derive"] }
3334
thiserror.workspace = true

deno_webgpu/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ use deno_core::op2;
66
use deno_core::OpState;
77
use deno_core::Resource;
88
use deno_core::ResourceId;
9+
use hashbrown::HashSet;
910
use serde::Deserialize;
1011
use serde::Serialize;
1112
use std::borrow::Cow;
1213
use std::cell::RefCell;
13-
use std::collections::HashSet;
1414
use std::rc::Rc;
1515

1616
use error::WebGpuResult;

deno_webgpu/pipeline.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use deno_core::op2;
55
use deno_core::OpState;
66
use deno_core::Resource;
77
use deno_core::ResourceId;
8+
use hashbrown::HashMap;
89
use serde::Deserialize;
910
use serde::Serialize;
1011
use std::borrow::Cow;
11-
use std::collections::HashMap;
1212
use std::rc::Rc;
1313

1414
use super::error::WebGpuError;

examples/features/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,6 @@ web-sys = { workspace = true, features = [
7474

7575
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
7676
wasm-bindgen-test.workspace = true
77+
78+
[lints.clippy]
79+
disallowed_types = "allow"

lock-analyzer/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ anyhow.workspace = true
1717
[dependencies.serde]
1818
workspace = true
1919
features = ["default", "serde_derive"]
20+
21+
[lints.clippy]
22+
disallowed_types = "allow"

naga/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ msl-out = []
4141
## If you want to enable MSL output it regardless of the target platform, use `naga/msl-out`.
4242
msl-out-if-target-apple = []
4343

44-
serialize = ["dep:serde", "bitflags/serde", "indexmap/serde"]
45-
deserialize = ["dep:serde", "bitflags/serde", "indexmap/serde"]
44+
serialize = ["dep:serde", "bitflags/serde", "hashbrown/serde", "indexmap/serde"]
45+
deserialize = [
46+
"dep:serde",
47+
"bitflags/serde",
48+
"hashbrown/serde",
49+
"indexmap/serde",
50+
]
4651
arbitrary = ["dep:arbitrary", "bitflags/arbitrary", "indexmap/arbitrary"]
4752
spv-in = ["dep:petgraph", "dep:spirv"]
4853
spv-out = ["dep:spirv"]
@@ -72,6 +77,7 @@ termcolor = { version = "1.4.1" }
7277
# termcolor minimum version was wrong and was fixed in
7378
# https://github.com/brendanzab/codespan/commit/e99c867339a877731437e7ee6a903a3d03b5439e
7479
codespan-reporting = { version = "0.11.0" }
80+
hashbrown.workspace = true
7581
rustc-hash.workspace = true
7682
indexmap.workspace = true
7783
log = "0.4"

naga/fuzz/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ path = "fuzz_targets/ir.rs"
5050
bench = false
5151
test = false
5252
doc = false
53+
54+
[lints.clippy]
55+
disallowed_types = "allow"

naga/fuzz/fuzz_targets/glsl_parser.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,32 @@
22

33
#[cfg(enable_fuzzing)]
44
mod fuzz {
5+
use std::iter::FromIterator;
6+
57
use arbitrary::Arbitrary;
68
use libfuzzer_sys::fuzz_target;
79
use naga::{
810
front::glsl::{Frontend, Options},
911
FastHashMap, ShaderStage,
1012
};
1113

12-
#[derive(Debug, Arbitrary)]
13-
enum ShaderStageProxy {
14-
Vertex,
15-
Fragment,
16-
Compute,
17-
}
18-
19-
impl From<ShaderStageProxy> for ShaderStage {
20-
fn from(proxy: ShaderStageProxy) -> Self {
21-
match proxy {
22-
ShaderStageProxy::Vertex => ShaderStage::Vertex,
23-
ShaderStageProxy::Fragment => ShaderStage::Fragment,
24-
ShaderStageProxy::Compute => ShaderStage::Compute,
25-
}
26-
}
27-
}
28-
2914
#[derive(Debug, Arbitrary)]
3015
struct OptionsProxy {
31-
pub stage: ShaderStageProxy,
32-
pub defines: FastHashMap<String, String>,
16+
pub stage: ShaderStage,
17+
pub defines: std::collections::HashMap<String, String>,
3318
}
3419

3520
impl From<OptionsProxy> for Options {
3621
fn from(proxy: OptionsProxy) -> Self {
3722
Options {
38-
stage: proxy.stage.into(),
39-
defines: proxy.defines,
23+
stage: proxy.stage,
24+
// NOTE: This is a workaround needed due to lack of rust-fuzz/arbitrary support for hashbrown.
25+
defines: FastHashMap::from_iter(
26+
proxy
27+
.defines
28+
.keys()
29+
.map(|k| (k.clone(), proxy.defines.get(&k.clone()).unwrap().clone())),
30+
),
4031
}
4132
}
4233
}

naga/src/back/glsl/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use crate::{
5151
valid, Handle, ShaderStage, TypeInner,
5252
};
5353
use features::FeaturesManager;
54+
use hashbrown::hash_map;
5455
use std::{
5556
cmp::Ordering,
5657
fmt::{self, Error as FmtError, Write},
@@ -4608,7 +4609,6 @@ impl<'a, W: Write> Writer<'a, W> {
46084609

46094610
/// Helper method used to produce the reflection info that's returned to the user
46104611
fn collect_reflection_info(&mut self) -> Result<ReflectionInfo, Error> {
4611-
use std::collections::hash_map::Entry;
46124612
let info = self.info.get_entry_point(self.entry_point_idx as usize);
46134613
let mut texture_mapping = crate::FastHashMap::default();
46144614
let mut uniforms = crate::FastHashMap::default();
@@ -4617,13 +4617,13 @@ impl<'a, W: Write> Writer<'a, W> {
46174617
let tex_name = self.reflection_names_globals[&sampling.image].clone();
46184618

46194619
match texture_mapping.entry(tex_name) {
4620-
Entry::Vacant(v) => {
4620+
hash_map::Entry::Vacant(v) => {
46214621
v.insert(TextureMapping {
46224622
texture: sampling.image,
46234623
sampler: Some(sampling.sampler),
46244624
});
46254625
}
4626-
Entry::Occupied(e) => {
4626+
hash_map::Entry::Occupied(e) => {
46274627
if e.get().sampler != Some(sampling.sampler) {
46284628
log::error!("Conflicting samplers for {}", e.key());
46294629
return Err(Error::ImageMultipleSamplers);
@@ -4641,13 +4641,13 @@ impl<'a, W: Write> Writer<'a, W> {
46414641
TypeInner::Image { .. } => {
46424642
let tex_name = self.reflection_names_globals[&handle].clone();
46434643
match texture_mapping.entry(tex_name) {
4644-
Entry::Vacant(v) => {
4644+
hash_map::Entry::Vacant(v) => {
46454645
v.insert(TextureMapping {
46464646
texture: handle,
46474647
sampler: None,
46484648
});
46494649
}
4650-
Entry::Occupied(_) => {
4650+
hash_map::Entry::Occupied(_) => {
46514651
// already used with a sampler, do nothing
46524652
}
46534653
}

naga/src/back/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl std::fmt::Display for Baked {
5555
/// the key must be the constant's identifier name.
5656
///
5757
/// The value may represent any of WGSL's concrete scalar types.
58-
pub type PipelineConstants = std::collections::HashMap<String, f64>;
58+
pub type PipelineConstants = hashbrown::HashMap<String, f64>;
5959

6060
/// Indentation level.
6161
#[derive(Clone, Copy)]

naga/src/back/pipeline_constants.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::{
66
Arena, Block, Constant, Expression, Function, Handle, Literal, Module, Override, Range, Scalar,
77
Span, Statement, TypeInner, WithSpan,
88
};
9-
use std::{borrow::Cow, collections::HashSet, mem};
9+
use hashbrown::HashSet;
10+
use std::{borrow::Cow, mem};
1011
use thiserror::Error;
1112

1213
#[derive(Error, Debug, Clone)]

naga/src/back/spv/recyclable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ impl<T> Recyclable for Vec<T> {
3838
}
3939
}
4040

41-
impl<K, V, S: Clone> Recyclable for std::collections::HashMap<K, V, S> {
41+
impl<K, V, S: Clone> Recyclable for hashbrown::HashMap<K, V, S> {
4242
fn recycle(mut self) -> Self {
4343
self.clear();
4444
self
4545
}
4646
}
4747

48-
impl<K, S: Clone> Recyclable for std::collections::HashSet<K, S> {
48+
impl<K, S: Clone> Recyclable for hashbrown::HashSet<K, S> {
4949
fn recycle(mut self) -> Self {
5050
self.clear();
5151
self

naga/src/back/spv/writer.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use crate::{
1212
proc::{Alignment, TypeResolution},
1313
valid::{FunctionInfo, ModuleInfo},
1414
};
15+
use hashbrown::hash_map::Entry;
1516
use spirv::Word;
16-
use std::collections::hash_map::Entry;
1717

1818
struct FunctionInterface<'a> {
1919
varying_ids: &'a mut Vec<Word>,
@@ -167,7 +167,11 @@ impl Writer {
167167
let selected = match self.capabilities_available {
168168
None => first,
169169
Some(ref available) => {
170-
match capabilities.iter().find(|cap| available.contains(cap)) {
170+
match capabilities
171+
.iter()
172+
// need explicit type for hashbrown::HashSet::contains fn call to keep rustc happy
173+
.find(|cap| available.contains::<spirv::Capability>(cap))
174+
{
171175
Some(&cap) => cap,
172176
None => {
173177
return Err(Error::MissingCapabilities(what, capabilities.to_vec()))

naga/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,15 @@ pub const BOOL_WIDTH: Bytes = 1;
283283
pub const ABSTRACT_WIDTH: Bytes = 8;
284284

285285
/// Hash map that is faster but not resilient to DoS attacks.
286-
pub type FastHashMap<K, T> = rustc_hash::FxHashMap<K, T>;
286+
/// (Similar to rustc_hash::FxHashMap but using hashbrown::HashMap instead of std::collections::HashMap.)
287+
/// To construct a new instance: `FastHashMap::default()`
288+
pub type FastHashMap<K, T> =
289+
hashbrown::HashMap<K, T, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
290+
287291
/// Hash set that is faster but not resilient to DoS attacks.
288-
pub type FastHashSet<K> = rustc_hash::FxHashSet<K>;
292+
/// (Similar to rustc_hash::FxHashSet but using hashbrown::HashSet instead of std::collections::HashMap.)
293+
pub type FastHashSet<K> =
294+
hashbrown::HashSet<K, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
289295

290296
/// Insertion-order-preserving hash set (`IndexSet<K>`), but with the same
291297
/// hasher as `FastHashSet<K>` (faster but not resilient to DoS attacks).
@@ -325,6 +331,7 @@ pub(crate) type NamedExpressions = FastIndexMap<Handle<Expression>, String>;
325331
pub struct EarlyDepthTest {
326332
pub conservative: Option<ConservativeDepth>,
327333
}
334+
328335
/// Enables adjusting depth without disabling early Z.
329336
///
330337
/// To use in a shader:

tests/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,6 @@ wasm-bindgen-futures.workspace = true
7070
wasm-bindgen-test.workspace = true
7171
wasm-bindgen.workspace = true
7272
web-sys = { workspace = true, features = ["CanvasRenderingContext2d", "Blob"] }
73+
74+
[lints.clippy]
75+
disallowed_types = "allow"

wgpu-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ strict_asserts = ["wgpu-types/strict_asserts"]
6060
indirect-validation = ["naga/wgsl-in"]
6161

6262
## Enables serialization via `serde` on common wgpu types.
63-
serde = ["dep:serde", "wgpu-types/serde", "arrayvec/serde"]
63+
serde = ["dep:serde", "wgpu-types/serde", "arrayvec/serde", "hashbrown/serde"]
6464

6565
## Enable API tracing.
6666
trace = ["dep:ron", "serde", "naga/serialize"]

wgpu-hal/src/dx12/sampler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! Nearly identical to the Vulkan sampler cache, with added descriptor heap management.
44
5-
use std::collections::{hash_map::Entry, HashMap};
5+
use hashbrown::{hash_map::Entry, HashMap};
66

77
use ordered_float::OrderedFloat;
88
use parking_lot::Mutex;

wgpu-hal/src/gles/device.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{conv, PrivateCapabilities};
22
use crate::auxil::map_naga_stage;
33
use glow::HasContext;
4+
use naga::FastHashMap;
45
use std::{
56
cmp::max,
67
convert::TryInto,
@@ -16,7 +17,7 @@ type ShaderStage<'a> = (
1617
naga::ShaderStage,
1718
&'a crate::ProgrammableStage<'a, super::ShaderModule>,
1819
);
19-
type NameBindingMap = rustc_hash::FxHashMap<String, (super::BindingRegister, u8)>;
20+
type NameBindingMap = FastHashMap<String, (super::BindingRegister, u8)>;
2021

2122
struct CompilationContext<'a> {
2223
layout: &'a super::PipelineLayout,

0 commit comments

Comments
 (0)