Skip to content

Commit 6e21f7a

Browse files
gents83ElabajabaniklaskorzgrovesNLjimblandy
authored
Arcanization of wgpu core resources (#3626)
Arcanization of wgpu_core resources --------- Co-authored-by: Elabajaba <[email protected]> Co-authored-by: Niklas Korz <[email protected]> Co-authored-by: grovesNL <[email protected]> Co-authored-by: Jim Blandy <[email protected]> Co-authored-by: Mauro Gentile <[email protected]> Co-authored-by: Sludge <[email protected]>
1 parent a827c18 commit 6e21f7a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+7311
-6998
lines changed

CHANGELOG.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ Bottom level categories:
4242

4343
### Changes
4444

45+
- Arcanization of wgpu core resources:
46+
Removed Token and LifeTime related management
47+
Removed RefCount and MultiRefCount in favour of using only Arc internal reference count
48+
Removing mut from resources and added instead internal members locks on demand or atomics operations
49+
Resources now implement Drop and destroy stuff when last Arc resources is released
50+
Resources hold an Arc in order to be able to implement Drop
51+
Resources have an utility to retrieve the id of the resource itself
52+
Remove all guards and just retrive the Arc needed on-demand to unlock registry of resources asap
53+
Verify correct resources release when unused or not needed
54+
Check Web and Metal compliation (thanks to @niklaskorz)
55+
Fix tests on all platforms
56+
Test a multithreaded scenario
57+
Storage is now holding only user-land resources, but Arc is keeping refcount for resources
58+
When user unregister a resource, it's not dropped if still in use due to refcount inside wgpu
59+
IdentityManager is now unique and free is called on resource drop instead of storage unregister
60+
Identity changes due to Arcanization and Registry being just the user reference
61+
Added MemLeaks test and fixing mem leaks
62+
By @gents83 in [#3626](https://github.com/gfx-rs/wgpu/pull/3626) and tnx also to @jimblandy, @nical, @Wumpf, @Elabajaba & @cwfitzgerald
63+
4564
#### General
4665

4766
- Log vulkan validation layer messages during instance creation and destruction: By @exrook in [#4586](https://github.com/gfx-rs/wgpu/pull/4586)
@@ -1122,7 +1141,7 @@ both `raw_window_handle::HasRawWindowHandle` and `raw_window_handle::HasRawDispl
11221141

11231142
#### Vulkan
11241143

1125-
- Fix `astc_hdr` formats support by @jinleili in [#2971]](https://github.com/gfx-rs/wgpu/pull/2971)
1144+
- Fix `astc_hdr` formats support by @jinleili in [#2971]](https://github.com/gfx-rs/wgpu/pull/2971)
11261145
- Update to Naga b209d911 (2022-9-1) to avoid generating SPIR-V that
11271146
violates Vulkan valid usage rules `VUID-StandaloneSpirv-Flat-06202`
11281147
and `VUID-StandaloneSpirv-Flat-04744`. By @jimblandy in
@@ -2331,4 +2350,4 @@ DeviceDescriptor {
23312350
- concept of the storage hub
23322351
- basic recording of passes and command buffers
23332352
- submission-based lifetime tracking and command buffer recycling
2334-
- automatic resource transitions
2353+
- automatic resource transitions

Cargo.lock

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

deno_webgpu/buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub async fn op_webgpu_buffer_get_map_async(
106106
2 => wgpu_core::device::HostMap::Write,
107107
_ => unreachable!(),
108108
},
109-
callback: wgpu_core::resource::BufferMapCallback::from_rust(callback),
109+
callback: Some(wgpu_core::resource::BufferMapCallback::from_rust(callback)),
110110
}
111111
))
112112
.err();

deno_webgpu/error.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ impl From<DeviceError> for WebGpuError {
104104
match err {
105105
DeviceError::Lost => WebGpuError::Lost,
106106
DeviceError::OutOfMemory => WebGpuError::OutOfMemory,
107-
DeviceError::ResourceCreationFailed
108-
| DeviceError::Invalid
109-
| DeviceError::WrongDevice => WebGpuError::Validation(fmt_err(&err)),
107+
_ => WebGpuError::Validation(fmt_err(&err)),
110108
}
111109
}
112110
}

deno_webgpu/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,10 +661,11 @@ pub async fn op_webgpu_request_device(
661661
limits: required_limits.unwrap_or_default(),
662662
};
663663

664-
let (device, maybe_err) = gfx_select!(adapter => instance.adapter_request_device(
664+
let (device, _queue, maybe_err) = gfx_select!(adapter => instance.adapter_request_device(
665665
adapter,
666666
&descriptor,
667667
std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new),
668+
(),
668669
()
669670
));
670671
if let Some(err) = maybe_err {

player/src/bin/play.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn main() {
5454
IdentityPassThroughFactory,
5555
wgt::InstanceDescriptor::default(),
5656
);
57-
let mut command_buffer_id_manager = wgc::identity::IdentityManager::default();
57+
let mut command_buffer_id_manager = wgc::identity::IdentityManager::new();
5858

5959
#[cfg(feature = "winit")]
6060
let surface = unsafe {
@@ -88,10 +88,11 @@ fn main() {
8888
let info = gfx_select!(adapter => global.adapter_get_info(adapter)).unwrap();
8989
log::info!("Picked '{}'", info.name);
9090
let id = wgc::id::TypedId::zip(1, 0, backend);
91-
let (_, error) = gfx_select!(adapter => global.adapter_request_device(
91+
let (_, _, error) = gfx_select!(adapter => global.adapter_request_device(
9292
adapter,
9393
&desc,
9494
None,
95+
id,
9596
id
9697
));
9798
if let Some(e) = error {

player/src/lib.rs

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,22 @@
1010

1111
use wgc::device::trace;
1212

13-
use std::{borrow::Cow, fmt::Debug, fs, marker::PhantomData, path::Path};
13+
use std::{borrow::Cow, fs, path::Path};
1414

15-
#[derive(Debug)]
16-
pub struct IdentityPassThrough<I>(PhantomData<I>);
15+
pub struct IdentityPassThroughFactory;
1716

18-
impl<I: Clone + Debug + wgc::id::TypedId> wgc::identity::IdentityHandler<I>
19-
for IdentityPassThrough<I>
20-
{
17+
impl<I: wgc::id::TypedId> wgc::identity::IdentityHandlerFactory<I> for IdentityPassThroughFactory {
2118
type Input = I;
22-
fn process(&self, id: I, backend: wgt::Backend) -> I {
23-
let (index, epoch, _backend) = id.unzip();
24-
I::zip(index, epoch, backend)
25-
}
26-
fn free(&self, _id: I) {}
27-
}
2819

29-
pub struct IdentityPassThroughFactory;
30-
31-
impl<I: Clone + Debug + wgc::id::TypedId> wgc::identity::IdentityHandlerFactory<I>
32-
for IdentityPassThroughFactory
33-
{
34-
type Filter = IdentityPassThrough<I>;
35-
fn spawn(&self) -> Self::Filter {
36-
IdentityPassThrough(PhantomData)
20+
fn input_to_id(id_in: Self::Input) -> I {
21+
id_in
3722
}
38-
}
39-
impl wgc::identity::GlobalIdentityHandlerFactory for IdentityPassThroughFactory {
40-
fn ids_are_generated_in_wgpu() -> bool {
23+
24+
fn autogenerate_ids() -> bool {
4125
false
4226
}
4327
}
28+
impl wgc::identity::GlobalIdentityHandlerFactory for IdentityPassThroughFactory {}
4429

4530
pub trait GlobalPlay {
4631
fn encode_commands<A: wgc::hal_api::HalApi>(
@@ -53,7 +38,7 @@ pub trait GlobalPlay {
5338
device: wgc::id::DeviceId,
5439
action: trace::Action,
5540
dir: &Path,
56-
comb_manager: &mut wgc::identity::IdentityManager,
41+
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::CommandBufferId>,
5742
);
5843
}
5944

@@ -168,10 +153,10 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
168153
device: wgc::id::DeviceId,
169154
action: trace::Action,
170155
dir: &Path,
171-
comb_manager: &mut wgc::identity::IdentityManager,
156+
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::CommandBufferId>,
172157
) {
173158
use wgc::device::trace::Action;
174-
log::info!("action {:?}", action);
159+
log::debug!("action {:?}", action);
175160
//TODO: find a way to force ID perishing without excessive `maintain()` calls.
176161
match action {
177162
Action::Init { .. } => {
@@ -269,7 +254,7 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
269254
self.bind_group_drop::<A>(id);
270255
}
271256
Action::CreateShaderModule { id, desc, data } => {
272-
log::info!("Creating shader from {}", data);
257+
log::debug!("Creating shader from {}", data);
273258
let code = fs::read_to_string(dir.join(&data)).unwrap();
274259
let source = if data.ends_with(".wgsl") {
275260
wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code.clone()))
@@ -390,7 +375,7 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
390375
let (encoder, error) = self.device_create_command_encoder::<A>(
391376
device,
392377
&wgt::CommandEncoderDescriptor { label: None },
393-
comb_manager.alloc(device.backend()),
378+
comb_manager.process(device.backend()),
394379
);
395380
if let Some(e) = error {
396381
panic!("{e}");

player/tests/data/bind-group.ron

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,6 @@
22
features: 0x0,
33
expectations: [], //not crash!
44
actions: [
5-
CreatePipelineLayout(Id(0, 1, Empty), (
6-
label: Some("empty"),
7-
bind_group_layouts: [],
8-
push_constant_ranges: [],
9-
)),
10-
CreateShaderModule(
11-
id: Id(0, 1, Empty),
12-
desc: (
13-
label: None,
14-
flags: (bits: 3),
15-
),
16-
data: "empty.wgsl",
17-
),
18-
CreateComputePipeline(
19-
id: Id(0, 1, Empty),
20-
desc: (
21-
label: None,
22-
layout: Some(Id(0, 1, Empty)),
23-
stage: (
24-
module: Id(0, 1, Empty),
25-
entry_point: "main",
26-
),
27-
),
28-
),
295
CreateBuffer(Id(0, 1, Empty), (
306
label: None,
317
size: 16,
@@ -58,16 +34,42 @@
5834
)
5935
],
6036
)),
37+
CreatePipelineLayout(Id(0, 1, Empty), (
38+
label: Some("empty"),
39+
bind_group_layouts: [
40+
Id(0, 1, Empty),
41+
],
42+
push_constant_ranges: [],
43+
)),
44+
CreateShaderModule(
45+
id: Id(0, 1, Empty),
46+
desc: (
47+
label: None,
48+
flags: (bits: 3),
49+
),
50+
data: "empty.wgsl",
51+
),
52+
CreateComputePipeline(
53+
id: Id(0, 1, Empty),
54+
desc: (
55+
label: None,
56+
layout: Some(Id(0, 1, Empty)),
57+
stage: (
58+
module: Id(0, 1, Empty),
59+
entry_point: "main",
60+
),
61+
),
62+
),
6163
Submit(1, [
6264
RunComputePass(
6365
base: (
6466
commands: [
65-
SetPipeline(Id(0, 1, Empty)),
6667
SetBindGroup(
6768
index: 0,
6869
num_dynamic_offsets: 0,
6970
bind_group_id: Id(0, 1, Empty),
7071
),
72+
SetPipeline(Id(0, 1, Empty)),
7173
],
7274
dynamic_offsets: [],
7375
string_data: [],

player/tests/data/zero-init-texture-binding.ron

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
format: "rgba8unorm",
5757
usage: 9, // STORAGE + COPY_SRC
5858
view_formats: [],
59-
)),
59+
)),
6060
CreateTextureView(
6161
id: Id(1, 1, Empty),
6262
parent_id: Id(1, 1, Empty),

0 commit comments

Comments
 (0)