Skip to content

Commit

Permalink
selectable wgpu backend
Browse files Browse the repository at this point in the history
  • Loading branch information
schell committed Aug 26, 2024
1 parent ee25de3 commit 129b610
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 16 deletions.
4 changes: 3 additions & 1 deletion crates/example-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ pub async fn main() {
viewport_canvas.set_height(wh);

let surface = surface_from_canvas(viewport_canvas.clone()).unwrap();
let ctx = Context::try_from_raw_window(ww, wh, surface).await.unwrap();
let ctx = Context::try_from_raw_window(ww, wh, None, surface)
.await
.unwrap();
let app = example::App::new(&ctx);

let window_resize = event::event_stream("resize", &dom_window);
Expand Down
2 changes: 1 addition & 1 deletion crates/example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl ApplicationHandler for OuterApp {
let window = Arc::new(event_loop.create_window(attributes).unwrap());

// Set up a new renderling context
let ctx = Context::try_from_window(window.clone()).unwrap();
let ctx = Context::try_from_window(None, window.clone()).unwrap();
let mut app = App::new(&ctx);
if let Some(file) = self.cli.model.as_ref() {
app.load(file.as_ref());
Expand Down
47 changes: 34 additions & 13 deletions crates/renderling/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Rendering context initialization and frame management.
use core::fmt::Debug;
use std::{
ops::Deref,
sync::{Arc, RwLock},
Expand Down Expand Up @@ -162,13 +163,13 @@ async fn device(
.await
}

fn new_instance() -> wgpu::Instance {
fn new_instance(backends: Option<wgpu::Backends>) -> wgpu::Instance {
log::trace!(
"creating instance - available backends: {:#?}",
wgpu::Instance::enabled_backend_features()
);
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let backends = wgpu::Backends::PRIMARY;
let backends = backends.unwrap_or(wgpu::Backends::PRIMARY);
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends,
..Default::default()
Expand Down Expand Up @@ -485,9 +486,13 @@ impl Context {
}
}

pub async fn try_new_headless(width: u32, height: u32) -> Result<Self, ContextError> {
pub async fn try_new_headless(
width: u32,
height: u32,
backends: Option<wgpu::Backends>,
) -> Result<Self, ContextError> {
log::trace!("creating headless context of size ({width}, {height})");
let instance = new_instance();
let instance = new_instance(backends);
let (adapter, device, queue, target) =
new_headless_device_queue_and_target(width, height, &instance).await?;
Ok(Self::new(target, adapter, device, queue))
Expand All @@ -496,18 +501,22 @@ impl Context {
pub async fn try_from_raw_window(
width: u32,
height: u32,
backends: Option<wgpu::Backends>,
window: impl Into<wgpu::SurfaceTarget<'static>>,
) -> Result<Self, ContextError> {
let instance = new_instance();
let instance = new_instance(backends);
let (adapter, device, queue, target) =
new_windowed_adapter_device_queue(width, height, &instance, window).await?;
Ok(Self::new(target, adapter, device, queue))
}

#[cfg(feature = "winit")]
pub async fn from_window_async(window: Arc<winit::window::Window>) -> Self {
pub async fn from_window_async(
backends: Option<wgpu::Backends>,
window: Arc<winit::window::Window>,
) -> Self {
let inner_size = window.inner_size();
Self::try_from_raw_window(inner_size.width, inner_size.height, window)
Self::try_from_raw_window(inner_size.width, inner_size.height, backends, window)
.await
.unwrap()
}
Expand All @@ -518,23 +527,35 @@ impl Context {
///
/// ## Panics
/// Panics if the context cannot be created.
pub fn from_window(window: Arc<winit::window::Window>) -> Self {
futures_lite::future::block_on(Self::from_window_async(window))
pub fn from_window(
backends: Option<wgpu::Backends>,
window: Arc<winit::window::Window>,
) -> Self {
futures_lite::future::block_on(Self::from_window_async(backends, window))
}

#[cfg(not(target_arch = "wasm32"))]
pub fn try_from_raw_window_handle(
window_handle: impl Into<wgpu::SurfaceTarget<'static>>,
width: u32,
height: u32,
backends: Option<wgpu::Backends>,
) -> Result<Self, ContextError> {
futures_lite::future::block_on(Self::try_from_raw_window(width, height, window_handle))
futures_lite::future::block_on(Self::try_from_raw_window(
width,
height,
backends,
window_handle,
))
}

#[cfg(all(feature = "winit", not(target_arch = "wasm32")))]
pub fn try_from_window(window: Arc<winit::window::Window>) -> Result<Self, ContextError> {
pub fn try_from_window(
backends: Option<wgpu::Backends>,
window: Arc<winit::window::Window>,
) -> Result<Self, ContextError> {
let inner_size = window.inner_size();
Self::try_from_raw_window_handle(window, inner_size.width, inner_size.height)
Self::try_from_raw_window_handle(window, inner_size.width, inner_size.height, backends)
}

/// Create a new headless renderer.
Expand All @@ -543,7 +564,7 @@ impl Context {
/// This function will panic if an adapter cannot be found. For example this
/// would happen on machines without a GPU.
pub fn headless(width: u32, height: u32) -> Self {
futures_lite::future::block_on(Self::try_new_headless(width, height)).unwrap()
futures_lite::future::block_on(Self::try_new_headless(width, height, None)).unwrap()
}

pub fn get_size(&self) -> UVec2 {
Expand Down
2 changes: 1 addition & 1 deletion crates/sandbox/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl winit::application::ApplicationHandler for App {
})
.with_title("renderling gltf viewer");
let window = Arc::new(event_loop.create_window(attributes).unwrap());
let ctx = Context::from_window(window.clone());
let ctx = Context::from_window(None, window.clone());
let stage = ctx.new_stage();
self.example = Some(Example { ctx, window, stage });
}
Expand Down

0 comments on commit 129b610

Please sign in to comment.