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

Commit

Permalink
Merge #281
Browse files Browse the repository at this point in the history
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 <kvarkus@gmail.com>
  • Loading branch information
bors[bot] and kvark authored Apr 27, 2020
2 parents 309cc1c + b7883e4 commit 49640d2
Show file tree
Hide file tree
Showing 12 changed files with 2,546 additions and 1,948 deletions.
18 changes: 7 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,23 @@ exclude = ["etc/**/*", "examples/**/*", "tests/**/*", "Cargo.lock", "target/**/*
[features]
default = []
# Make Vulkan backend available on platforms where it is by default not, e.g. macOS
vulkan = ["wgn/vulkan-portability"]

[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgn]
package = "wgpu-native"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "49dbe08f37f8396cff0d6672667a48116ec487f5"
vulkan = ["wgc/gfx-backend-vulkan"]

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

[dependencies.wgt]
package = "wgpu-types"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "49dbe08f37f8396cff0d6672667a48116ec487f5"
rev = "5c172dd4756aa152b4f3350e624d7b1b5d24ddda"

[dependencies]
arrayvec = "0.5"
futures = "0.3"
smallvec = "1"
raw-window-handle = "0.3"
parking_lot = "0.10"
Expand All @@ -54,7 +49,6 @@ png = "0.15"
winit = { version = "0.22.1", features = ["web-sys"] }
rand = { version = "0.7.2", features = ["wasm-bindgen"] }
bytemuck = "1"
futures = "0.3"

[[example]]
name="hello-compute"
Expand All @@ -64,7 +58,6 @@ test = true
[patch.crates-io]
#wgpu-types = { version = "0.5.0", path = "../wgpu/wgpu-types" }
#wgpu-core = { version = "0.5.0", path = "../wgpu/wgpu-core" }
#wgpu-native = { version = "0.5.0", path = "../wgpu/wgpu-native" }
#gfx-hal = { version = "0.5.0", path = "../gfx/src/hal" }
#gfx-backend-empty = { version = "0.5.0", path = "../gfx/src/backend/empty" }
#gfx-backend-vulkan = { version = "0.5.0", path = "../gfx/src/backend/vulkan" }
Expand All @@ -78,6 +71,9 @@ wasm-bindgen-futures = { git = "https://github.com/rustwasm/wasm-bindgen" }
web-sys = { git = "https://github.com/rustwasm/wasm-bindgen" }
js-sys = { git = "https://github.com/rustwasm/wasm-bindgen" }

[target.'cfg(target_os = "macos")'.dependencies]
objc = "0.2.7"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
env_logger = "0.7"

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

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.

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.
wgpu-rs can target both the natively supported backends and WASM directly.

## Gallery

Expand Down
24 changes: 13 additions & 11 deletions examples/capture/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ use std::fs::File;
use std::mem::size_of;

async fn run() {
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let adapter = wgpu::Instance::new()
.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();

let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
Expand All @@ -22,7 +23,8 @@ async fn run() {
},
limits: wgpu::Limits::default(),
})
.await;
.await
.unwrap();

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

queue.submit(&[command_buffer]);
queue.submit(Some(command_buffer));

// Note that we're not calling `.await` here.
let buffer_future = output_buffer.map_read(0, (size * size) as u64 * size_of::<u32>() as u64);
Expand Down
19 changes: 10 additions & 9 deletions examples/describe/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/// This example shows how to describe the adapter in use.
async fn run() {
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let adapter = wgpu::Instance::new()
.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();

#[cfg(not(target_arch = "wasm32"))]
println!("{:?}", adapter.get_info())
Expand Down
37 changes: 20 additions & 17 deletions examples/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,23 @@ pub trait Example: 'static + Sized {
async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
log::info!("Initializing the surface...");

let (size, surface) = {
let instance = wgpu::Instance::new();
let (size, surface) = unsafe {
let size = window.inner_size();
let surface = wgpu::Surface::create(&window);
let surface = instance.create_surface(&window);
(size, surface)
};

let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let adapter = instance
.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();

let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
Expand All @@ -72,7 +74,8 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
},
limits: wgpu::Limits::default(),
})
.await;
.await
.unwrap();

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

log::info!("Initializing the example...");
let (mut example, init_command_buf) = E::init(&sc_desc, &device);
if let Some(command_buf) = init_command_buf {
queue.submit(&[command_buf]);
if init_command_buf.is_some() {
queue.submit(init_command_buf);
}

log::info!("Entering render loop...");
Expand All @@ -112,8 +115,8 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
sc_desc.height = size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
let command_buf = example.resize(&sc_desc, &device);
if let Some(command_buf) = command_buf {
queue.submit(&[command_buf]);
if command_buf.is_some() {
queue.submit(command_buf);
}
}
event::Event::WindowEvent { event, .. } => match event {
Expand All @@ -138,7 +141,7 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
.get_next_texture()
.expect("Timeout when acquiring next swap chain texture");
let command_buf = example.render(&frame, &device);
queue.submit(&[command_buf]);
queue.submit(Some(command_buf));
}
_ => {}
}
Expand Down
25 changes: 14 additions & 11 deletions examples/hello-compute/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
let slice_size = numbers.len() * std::mem::size_of::<u32>();
let size = slice_size as wgpu::BufferAddress;

let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let instace = wgpu::Instance::new();
let adapter = instace
.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();

let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
Expand All @@ -37,7 +39,8 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
},
limits: wgpu::Limits::default(),
})
.await;
.await
.unwrap();

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

queue.submit(&[encoder.finish()]);
queue.submit(Some(encoder.finish()));

// Note that we're not calling `.await` here.
let buffer_future = staging_buffer.map_read(0, size);
Expand Down
34 changes: 16 additions & 18 deletions examples/hello-triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ use winit::{

async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::TextureFormat) {
let size = window.inner_size();
let surface = wgpu::Surface::create(&window);

let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let instance = wgpu::Instance::new();
let surface = unsafe { instance.create_surface(&window) };
let adapter = instance
.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();

let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
Expand All @@ -25,7 +26,8 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::
},
limits: wgpu::Limits::default(),
})
.await;
.await
.unwrap();

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

queue.submit(&[encoder.finish()]);
queue.submit(Some(encoder.finish()));
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
Expand Down Expand Up @@ -150,10 +152,6 @@ fn main() {
.ok()
})
.expect("couldn't append canvas to document body");
wasm_bindgen_futures::spawn_local(run(
event_loop,
window,
wgpu::TextureFormat::Bgra8Unorm,
));
wasm_bindgen_futures::spawn_local(run(event_loop, window, wgpu::TextureFormat::Bgra8Unorm));
}
}
Loading

0 comments on commit 49640d2

Please sign in to comment.