Skip to content
This repository was archived by the owner on Jun 18, 2021. It is now read-only.

Commit 49640d2

Browse files
bors[bot]kvark
andauthored
Merge #281
281: The Context trait r=grovesNL a=kvark The main motivation here is to avoid blocking the wgpu-core updates by `wgpu-native`. Instead, `wgpu-native` becomes a branch, and the dependency of `wgpu-rs` -> `wgpu-native` starts adhering to the contract/API of the standard webgpu-native headers. The biggest change is the introduction of the Context trait. I recall us discussing 2 downsides to having this trait: 1. inconvenient for the users to include. This is a non-issue here, since it's private. 2. more code to maintain. This is less of an issue if we aim to have 3 backends. What this gives in return is a well established contract with the backends. Unlike gfx-rs, the backend code is right here, a part of the crate, so the contract is only for internal use. Fixes #156 : the "direct" implementation of it goes straight to wgpu-core. What this gives us is less overhead for command recording, since there is no longer an extra indirection on every command, and no heap allocation at the end of a render pass. The downside of this PR is one extra `Arc` (with addref) per object. This commit also has small improvements: - consuming command buffers on submit (Fixes #267) - Instance type - proper call to destructors - fallible `request_device` Co-authored-by: Dzmitry Malyshau <[email protected]>
2 parents 309cc1c + b7883e4 commit 49640d2

File tree

12 files changed

+2546
-1948
lines changed

12 files changed

+2546
-1948
lines changed

Cargo.toml

+7-11
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,23 @@ exclude = ["etc/**/*", "examples/**/*", "tests/**/*", "Cargo.lock", "target/**/*
2121
[features]
2222
default = []
2323
# Make Vulkan backend available on platforms where it is by default not, e.g. macOS
24-
vulkan = ["wgn/vulkan-portability"]
25-
26-
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgn]
27-
package = "wgpu-native"
28-
version = "0.5"
29-
git = "https://github.com/gfx-rs/wgpu"
30-
rev = "49dbe08f37f8396cff0d6672667a48116ec487f5"
24+
vulkan = ["wgc/gfx-backend-vulkan"]
3125

3226
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgc]
3327
package = "wgpu-core"
3428
version = "0.5"
3529
git = "https://github.com/gfx-rs/wgpu"
36-
rev = "49dbe08f37f8396cff0d6672667a48116ec487f5"
30+
rev = "5c172dd4756aa152b4f3350e624d7b1b5d24ddda"
3731

3832
[dependencies.wgt]
3933
package = "wgpu-types"
4034
version = "0.5"
4135
git = "https://github.com/gfx-rs/wgpu"
42-
rev = "49dbe08f37f8396cff0d6672667a48116ec487f5"
36+
rev = "5c172dd4756aa152b4f3350e624d7b1b5d24ddda"
4337

4438
[dependencies]
4539
arrayvec = "0.5"
40+
futures = "0.3"
4641
smallvec = "1"
4742
raw-window-handle = "0.3"
4843
parking_lot = "0.10"
@@ -54,7 +49,6 @@ png = "0.15"
5449
winit = { version = "0.22.1", features = ["web-sys"] }
5550
rand = { version = "0.7.2", features = ["wasm-bindgen"] }
5651
bytemuck = "1"
57-
futures = "0.3"
5852

5953
[[example]]
6054
name="hello-compute"
@@ -64,7 +58,6 @@ test = true
6458
[patch.crates-io]
6559
#wgpu-types = { version = "0.5.0", path = "../wgpu/wgpu-types" }
6660
#wgpu-core = { version = "0.5.0", path = "../wgpu/wgpu-core" }
67-
#wgpu-native = { version = "0.5.0", path = "../wgpu/wgpu-native" }
6861
#gfx-hal = { version = "0.5.0", path = "../gfx/src/hal" }
6962
#gfx-backend-empty = { version = "0.5.0", path = "../gfx/src/backend/empty" }
7063
#gfx-backend-vulkan = { version = "0.5.0", path = "../gfx/src/backend/vulkan" }
@@ -78,6 +71,9 @@ wasm-bindgen-futures = { git = "https://github.com/rustwasm/wasm-bindgen" }
7871
web-sys = { git = "https://github.com/rustwasm/wasm-bindgen" }
7972
js-sys = { git = "https://github.com/rustwasm/wasm-bindgen" }
8073

74+
[target.'cfg(target_os = "macos")'.dependencies]
75+
objc = "0.2.7"
76+
8177
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
8278
env_logger = "0.7"
8379

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
wgpu-rs is an idiomatic Rust wrapper over [wgpu-core](https://github.com/gfx-rs/wgpu). It's designed to be suitable for general purpose graphics and computation needs of Rust community.
1010

11-
Currently wgpu-rs works on native platforms, but [WASM support is currently being added](https://github.com/gfx-rs/wgpu-rs/issues/101) as well.
11+
wgpu-rs can target both the natively supported backends and WASM directly.
1212

1313
## Gallery
1414

examples/capture/main.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ use std::fs::File;
55
use std::mem::size_of;
66

77
async fn run() {
8-
let adapter = wgpu::Adapter::request(
9-
&wgpu::RequestAdapterOptions {
10-
power_preference: wgpu::PowerPreference::Default,
11-
compatible_surface: None,
12-
},
13-
wgpu::BackendBit::PRIMARY,
14-
)
15-
.await
16-
.unwrap();
8+
let adapter = wgpu::Instance::new()
9+
.request_adapter(
10+
&wgpu::RequestAdapterOptions {
11+
power_preference: wgpu::PowerPreference::Default,
12+
compatible_surface: None,
13+
},
14+
wgpu::BackendBit::PRIMARY,
15+
)
16+
.await
17+
.unwrap();
1718

1819
let (device, queue) = adapter
1920
.request_device(&wgpu::DeviceDescriptor {
@@ -22,7 +23,8 @@ async fn run() {
2223
},
2324
limits: wgpu::Limits::default(),
2425
})
25-
.await;
26+
.await
27+
.unwrap();
2628

2729
// Rendered image is 256×256 with 32-bit RGBA color
2830
let size = 256u32;
@@ -86,7 +88,7 @@ async fn run() {
8688
encoder.finish()
8789
};
8890

89-
queue.submit(&[command_buffer]);
91+
queue.submit(Some(command_buffer));
9092

9193
// Note that we're not calling `.await` here.
9294
let buffer_future = output_buffer.map_read(0, (size * size) as u64 * size_of::<u32>() as u64);

examples/describe/main.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
/// This example shows how to describe the adapter in use.
22
async fn run() {
3-
let adapter = wgpu::Adapter::request(
4-
&wgpu::RequestAdapterOptions {
5-
power_preference: wgpu::PowerPreference::Default,
6-
compatible_surface: None,
7-
},
8-
wgpu::BackendBit::PRIMARY,
9-
)
10-
.await
11-
.unwrap();
3+
let adapter = wgpu::Instance::new()
4+
.request_adapter(
5+
&wgpu::RequestAdapterOptions {
6+
power_preference: wgpu::PowerPreference::Default,
7+
compatible_surface: None,
8+
},
9+
wgpu::BackendBit::PRIMARY,
10+
)
11+
.await
12+
.unwrap();
1213

1314
#[cfg(not(target_arch = "wasm32"))]
1415
println!("{:?}", adapter.get_info())

examples/framework.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,23 @@ pub trait Example: 'static + Sized {
4949
async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
5050
log::info!("Initializing the surface...");
5151

52-
let (size, surface) = {
52+
let instance = wgpu::Instance::new();
53+
let (size, surface) = unsafe {
5354
let size = window.inner_size();
54-
let surface = wgpu::Surface::create(&window);
55+
let surface = instance.create_surface(&window);
5556
(size, surface)
5657
};
5758

58-
let adapter = wgpu::Adapter::request(
59-
&wgpu::RequestAdapterOptions {
60-
power_preference: wgpu::PowerPreference::Default,
61-
compatible_surface: Some(&surface),
62-
},
63-
wgpu::BackendBit::PRIMARY,
64-
)
65-
.await
66-
.unwrap();
59+
let adapter = instance
60+
.request_adapter(
61+
&wgpu::RequestAdapterOptions {
62+
power_preference: wgpu::PowerPreference::Default,
63+
compatible_surface: Some(&surface),
64+
},
65+
wgpu::BackendBit::PRIMARY,
66+
)
67+
.await
68+
.unwrap();
6769

6870
let (device, queue) = adapter
6971
.request_device(&wgpu::DeviceDescriptor {
@@ -72,7 +74,8 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
7274
},
7375
limits: wgpu::Limits::default(),
7476
})
75-
.await;
77+
.await
78+
.unwrap();
7679

7780
let mut sc_desc = wgpu::SwapChainDescriptor {
7881
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
@@ -90,8 +93,8 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
9093

9194
log::info!("Initializing the example...");
9295
let (mut example, init_command_buf) = E::init(&sc_desc, &device);
93-
if let Some(command_buf) = init_command_buf {
94-
queue.submit(&[command_buf]);
96+
if init_command_buf.is_some() {
97+
queue.submit(init_command_buf);
9598
}
9699

97100
log::info!("Entering render loop...");
@@ -112,8 +115,8 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
112115
sc_desc.height = size.height;
113116
swap_chain = device.create_swap_chain(&surface, &sc_desc);
114117
let command_buf = example.resize(&sc_desc, &device);
115-
if let Some(command_buf) = command_buf {
116-
queue.submit(&[command_buf]);
118+
if command_buf.is_some() {
119+
queue.submit(command_buf);
117120
}
118121
}
119122
event::Event::WindowEvent { event, .. } => match event {
@@ -138,7 +141,7 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
138141
.get_next_texture()
139142
.expect("Timeout when acquiring next swap chain texture");
140143
let command_buf = example.render(&frame, &device);
141-
queue.submit(&[command_buf]);
144+
queue.submit(Some(command_buf));
142145
}
143146
_ => {}
144147
}

examples/hello-compute/main.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
2020
let slice_size = numbers.len() * std::mem::size_of::<u32>();
2121
let size = slice_size as wgpu::BufferAddress;
2222

23-
let adapter = wgpu::Adapter::request(
24-
&wgpu::RequestAdapterOptions {
25-
power_preference: wgpu::PowerPreference::Default,
26-
compatible_surface: None,
27-
},
28-
wgpu::BackendBit::PRIMARY,
29-
)
30-
.await
31-
.unwrap();
23+
let instace = wgpu::Instance::new();
24+
let adapter = instace
25+
.request_adapter(
26+
&wgpu::RequestAdapterOptions {
27+
power_preference: wgpu::PowerPreference::Default,
28+
compatible_surface: None,
29+
},
30+
wgpu::BackendBit::PRIMARY,
31+
)
32+
.await
33+
.unwrap();
3234

3335
let (device, queue) = adapter
3436
.request_device(&wgpu::DeviceDescriptor {
@@ -37,7 +39,8 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
3739
},
3840
limits: wgpu::Limits::default(),
3941
})
40-
.await;
42+
.await
43+
.unwrap();
4144

4245
let cs = include_bytes!("shader.comp.spv");
4346
let cs_module =
@@ -103,7 +106,7 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
103106
}
104107
encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size);
105108

106-
queue.submit(&[encoder.finish()]);
109+
queue.submit(Some(encoder.finish()));
107110

108111
// Note that we're not calling `.await` here.
109112
let buffer_future = staging_buffer.map_read(0, size);

examples/hello-triangle/main.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ use winit::{
66

77
async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::TextureFormat) {
88
let size = window.inner_size();
9-
let surface = wgpu::Surface::create(&window);
10-
11-
let adapter = wgpu::Adapter::request(
12-
&wgpu::RequestAdapterOptions {
13-
power_preference: wgpu::PowerPreference::Default,
14-
compatible_surface: Some(&surface),
15-
},
16-
wgpu::BackendBit::PRIMARY,
17-
)
18-
.await
19-
.unwrap();
9+
let instance = wgpu::Instance::new();
10+
let surface = unsafe { instance.create_surface(&window) };
11+
let adapter = instance
12+
.request_adapter(
13+
&wgpu::RequestAdapterOptions {
14+
power_preference: wgpu::PowerPreference::Default,
15+
compatible_surface: Some(&surface),
16+
},
17+
wgpu::BackendBit::PRIMARY,
18+
)
19+
.await
20+
.unwrap();
2021

2122
let (device, queue) = adapter
2223
.request_device(&wgpu::DeviceDescriptor {
@@ -25,7 +26,8 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::
2526
},
2627
limits: wgpu::Limits::default(),
2728
})
28-
.await;
29+
.await
30+
.unwrap();
2931

3032
let vs = include_bytes!("shader.vert.spv");
3133
let vs_module =
@@ -116,7 +118,7 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::
116118
rpass.draw(0..3, 0..1);
117119
}
118120

119-
queue.submit(&[encoder.finish()]);
121+
queue.submit(Some(encoder.finish()));
120122
}
121123
Event::WindowEvent {
122124
event: WindowEvent::CloseRequested,
@@ -150,10 +152,6 @@ fn main() {
150152
.ok()
151153
})
152154
.expect("couldn't append canvas to document body");
153-
wasm_bindgen_futures::spawn_local(run(
154-
event_loop,
155-
window,
156-
wgpu::TextureFormat::Bgra8Unorm,
157-
));
155+
wasm_bindgen_futures::spawn_local(run(event_loop, window, wgpu::TextureFormat::Bgra8Unorm));
158156
}
159157
}

0 commit comments

Comments
 (0)