diff --git a/examples/capture/main.rs b/examples/capture/main.rs index 50b7bf4d5..842593775 100644 --- a/examples/capture/main.rs +++ b/examples/capture/main.rs @@ -13,6 +13,7 @@ async fn run() { }, wgpu::BackendBit::PRIMARY, ) + .await .unwrap(); let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor { @@ -20,7 +21,8 @@ async fn run() { anisotropic_filtering: false, }, limits: wgpu::Limits::default(), - }); + }) + .await; // Rendered image is 256×256 with 32-bit RGBA color let size = 256u32; diff --git a/examples/describe/main.rs b/examples/describe/main.rs index bde3b5d17..131621ae1 100644 --- a/examples/describe/main.rs +++ b/examples/describe/main.rs @@ -1,13 +1,17 @@ /// This example shows how to describe the adapter in use. fn main() { env_logger::init(); + futures::executor::block_on(run()); +} +async fn run() { let adapter = wgpu::Adapter::request( &wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::Default, }, wgpu::BackendBit::PRIMARY, ) + .await .unwrap(); println!("{:?}", adapter.get_info()) diff --git a/examples/framework.rs b/examples/framework.rs index c5d2045e2..bbadbc261 100644 --- a/examples/framework.rs +++ b/examples/framework.rs @@ -52,7 +52,7 @@ pub trait Example: 'static + Sized { ) -> wgpu::CommandBuffer; } -pub fn run(title: &str) { +async fn run_async(title: &str) { use winit::{ event, event_loop::{ControlFlow, EventLoop}, @@ -105,6 +105,7 @@ pub fn run(title: &str) { }, wgpu::BackendBit::PRIMARY, ) + .await .unwrap(); let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor { @@ -112,7 +113,8 @@ pub fn run(title: &str) { anisotropic_filtering: false, }, limits: wgpu::Limits::default(), - }); + }) + .await; let mut sc_desc = wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, @@ -180,6 +182,10 @@ pub fn run(title: &str) { }); } +pub fn run(title: &str) { + futures::executor::block_on(run_async::(title)); +} + // This allows treating the framework as a standalone example, // thus avoiding listing the example names in `Cargo.toml`. #[allow(dead_code)] diff --git a/examples/hello-compute/main.rs b/examples/hello-compute/main.rs index 655c3119a..716563630 100644 --- a/examples/hello-compute/main.rs +++ b/examples/hello-compute/main.rs @@ -2,18 +2,18 @@ use std::{convert::TryInto as _, str::FromStr}; use zerocopy::AsBytes as _; async fn run() { - env_logger::init(); - - // For now this just panics if you didn't pass numbers. Could add proper error handling. - if std::env::args().len() == 1 { - panic!("You must pass a list of positive integers!") - } - let numbers: Vec = std::env::args() - .skip(1) - .map(|s| u32::from_str(&s).expect("You must pass a list of positive integers!")) - .collect(); + let numbers = if std::env::args().len() == 1 { + let default = vec![1, 2, 3, 4]; + log::info!("No numbers were provided, defaulting to {:?}", default); + default + } else { + std::env::args() + .skip(1) + .map(|s| u32::from_str(&s).expect("You must pass a list of positive integers!")) + .collect() + }; - println!("Times: {:?}", execute_gpu(numbers).await); + log::info!("Times: {:?}", execute_gpu(numbers).await); } async fn execute_gpu(numbers: Vec) -> Vec { @@ -26,6 +26,7 @@ async fn execute_gpu(numbers: Vec) -> Vec { }, wgpu::BackendBit::PRIMARY, ) + .await .unwrap(); let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor { @@ -33,7 +34,8 @@ async fn execute_gpu(numbers: Vec) -> Vec { anisotropic_filtering: false, }, limits: wgpu::Limits::default(), - }); + }) + .await; let cs = include_bytes!("shader.comp.spv"); let cs_module = @@ -108,6 +110,7 @@ async fn execute_gpu(numbers: Vec) -> Vec { } fn main() { + env_logger::init(); futures::executor::block_on(run()); } diff --git a/examples/hello-triangle/main.rs b/examples/hello-triangle/main.rs index a2050decf..edee6ef7e 100644 --- a/examples/hello-triangle/main.rs +++ b/examples/hello-triangle/main.rs @@ -1,39 +1,12 @@ -fn main() { - use winit::{ - event, - event_loop::{ControlFlow, EventLoop}, - }; - - env_logger::init(); - let event_loop = EventLoop::new(); - - #[cfg(not(feature = "gl"))] - let (window, size, surface) = { - let window = winit::window::Window::new(&event_loop).unwrap(); - let size = window.inner_size(); - let surface = wgpu::Surface::create(&window); - (window, size, surface) - }; - - #[cfg(feature = "gl")] - let (window, instance, size, surface) = { - let wb = winit::WindowBuilder::new(); - let cb = wgpu::glutin::ContextBuilder::new().with_vsync(true); - let context = cb.build_windowed(wb, &event_loop).unwrap(); - - let size = context - .window() - .get_inner_size() - .unwrap() - .to_physical(context.window().get_hidpi_factor()); +use winit::{ + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::Window +}; - let (context, window) = unsafe { context.make_current().unwrap().split() }; - - let instance = wgpu::Instance::new(context); - let surface = instance.get_surface(); - - (window, instance, size, surface) - }; +async fn run(event_loop: EventLoop<()>, window: Window) { + let size = window.inner_size(); + let surface = wgpu::Surface::create(&window); let adapter = wgpu::Adapter::request( &wgpu::RequestAdapterOptions { @@ -41,6 +14,7 @@ fn main() { }, wgpu::BackendBit::PRIMARY, ) + .await .unwrap(); let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor { @@ -48,7 +22,8 @@ fn main() { anisotropic_filtering: false, }, limits: wgpu::Limits::default(), - }); + }) + .await; let vs = include_bytes!("shader.vert.spv"); let vs_module = @@ -113,13 +88,13 @@ fn main() { event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Poll; match event { - event::Event::MainEventsCleared => window.request_redraw(), - event::Event::WindowEvent { event: event::WindowEvent::Resized(size), .. } => { + Event::MainEventsCleared => window.request_redraw(), + Event::WindowEvent { event: WindowEvent::Resized(size), .. } => { sc_desc.width = size.width; sc_desc.height = size.height; swap_chain = device.create_swap_chain(&surface, &sc_desc); } - event::Event::RedrawRequested(_) => { + Event::RedrawRequested(_) => { let frame = swap_chain .get_next_texture() .expect("Timeout when acquiring next swap chain texture"); @@ -143,11 +118,17 @@ fn main() { queue.submit(&[encoder.finish()]); } - event::Event::WindowEvent { - event: event::WindowEvent::CloseRequested, + Event::WindowEvent { + event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit, _ => {} } }); } +fn main() { + let event_loop = EventLoop::new(); + let window = winit::window::Window::new(&event_loop).unwrap(); + env_logger::init(); + futures::executor::block_on(run(event_loop, window)); +} diff --git a/src/backend/mod.rs b/src/backend/mod.rs new file mode 100644 index 000000000..c59ade973 --- /dev/null +++ b/src/backend/mod.rs @@ -0,0 +1 @@ +pub(crate) mod native_gpu_future; diff --git a/src/future.rs b/src/backend/native_gpu_future.rs similarity index 100% rename from src/future.rs rename to src/backend/native_gpu_future.rs diff --git a/src/lib.rs b/src/lib.rs index 0a3358864..bca88b7e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,7 @@ //! A cross-platform graphics and compute library based on WebGPU. -mod future; -use future::GpuFutureCompletion; -pub use future::GpuFuture; +mod backend; +use crate::backend::native_gpu_future; #[macro_use] mod macros; @@ -12,6 +11,7 @@ use smallvec::SmallVec; use std::{ ffi::CString, + future::Future, ops::Range, ptr, slice, @@ -501,7 +501,7 @@ impl Adapter { /// Some options are "soft", so treated as non-mandatory. Others are "hard". /// /// If no adapters are found that suffice all the "hard" options, `None` is returned. - pub fn request(options: &RequestAdapterOptions, backends: BackendBit) -> Option { + pub async fn request(options: &RequestAdapterOptions, backends: BackendBit) -> Option { unsafe extern "C" fn adapter_callback( id: wgc::id::AdapterId, user_data: *mut std::ffi::c_void, @@ -527,7 +527,7 @@ impl Adapter { /// # Panics /// /// Panics if the extensions specified by `desc` are not supported by this adapter. - pub fn request_device(&self, desc: &DeviceDescriptor) -> (Device, Queue) { + pub async fn request_device(&self, desc: &DeviceDescriptor) -> (Device, Queue) { let device = Device { id: wgn::wgpu_adapter_request_device(self.id, Some(desc)), temp: Temp::default(), @@ -910,22 +910,22 @@ impl Drop for BufferAsyncMapping { struct BufferMapReadFutureUserData { size: BufferAddress, - completion: GpuFutureCompletion, + completion: native_gpu_future::GpuFutureCompletion, buffer_id: wgc::id::BufferId, } struct BufferMapWriteFutureUserData { size: BufferAddress, - completion: GpuFutureCompletion, + completion: native_gpu_future::GpuFutureCompletion, buffer_id: wgc::id::BufferId, } impl Buffer { /// Map the buffer for reading. The result is returned in a future. - pub fn map_read(&self, start: BufferAddress, size: BufferAddress) -> GpuFuture + pub fn map_read(&self, start: BufferAddress, size: BufferAddress) -> impl Future { - let (future, completion) = future::new_gpu_future(self.device_id); + let (future, completion) = native_gpu_future::new_gpu_future(self.device_id); extern "C" fn buffer_map_read_future_wrapper( status: wgc::resource::BufferMapAsyncStatus, @@ -963,9 +963,9 @@ impl Buffer { } /// Map the buffer for writing. The result is returned in a future. - pub fn map_write(&self, start: BufferAddress, size: BufferAddress) -> GpuFuture + pub fn map_write(&self, start: BufferAddress, size: BufferAddress) -> impl Future { - let (future, completion) = future::new_gpu_future(self.device_id); + let (future, completion) = native_gpu_future::new_gpu_future(self.device_id); extern "C" fn buffer_map_write_future_wrapper( status: wgc::resource::BufferMapAsyncStatus,