From 4fec53c285aa8d77f0f4371d57fd12a9d93c6bda Mon Sep 17 00:00:00 2001 From: stevenhuyn <18359644+stevenhuyn@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:02:58 -0700 Subject: [PATCH] Upgrade to wgpu 19 https://github.com/sotrh/learn-wgpu/blob/0.19/code/beginner/tutorial5-textures/src/lib.rs --- cubeway/Cargo.toml | 9 ++- cubeway/src/camera.rs | 23 +++---- cubeway/src/lib.rs | 136 ++++++++++++++++++++++-------------------- 3 files changed, 88 insertions(+), 80 deletions(-) diff --git a/cubeway/Cargo.toml b/cubeway/Cargo.toml index 236e215..f0f1db9 100644 --- a/cubeway/Cargo.toml +++ b/cubeway/Cargo.toml @@ -15,11 +15,11 @@ path = "src/main.rs" [dependencies] wasm-bindgen = "0.2" -winit = "0.28" +winit = { version = "0.29", features = ["rwh_05"] } cgmath = "0.18" env_logger = "0.10" log = "0.4" -wgpu = "0.18" +wgpu = "0.19" cfg-if = "1" pollster = "0.3" bytemuck = { version = "1.12", features = [ "derive" ] } @@ -28,7 +28,7 @@ anyhow = "1.0" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.6" -wgpu = { version = "0.18", features = [] } +wgpu = { version = "0.19", features = [] } console_log = "1.0" wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" @@ -167,6 +167,5 @@ web-sys = { version = "0.3", features = [ - - \ No newline at end of file + diff --git a/cubeway/src/camera.rs b/cubeway/src/camera.rs index 79d7750..8e1a480 100644 --- a/cubeway/src/camera.rs +++ b/cubeway/src/camera.rs @@ -1,5 +1,8 @@ use cgmath::{InnerSpace, SquareMatrix}; -use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent}; +use winit::{ + event::{ElementState, KeyEvent, WindowEvent}, + keyboard::{KeyCode, PhysicalKey}, +}; #[rustfmt::skip] pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4 = cgmath::Matrix4::new( @@ -85,37 +88,37 @@ impl CameraController { pub fn process_events(&mut self, event: &WindowEvent) -> bool { match event { WindowEvent::KeyboardInput { - input: - KeyboardInput { + event: + KeyEvent { state, - virtual_keycode: Some(keycode), + physical_key: PhysicalKey::Code(keycode), .. }, .. } => { let is_pressed = *state == ElementState::Pressed; match keycode { - VirtualKeyCode::Space => { + KeyCode::Space => { self.is_up_pressed = is_pressed; true } - VirtualKeyCode::LShift => { + KeyCode::ShiftLeft => { self.is_down_pressed = is_pressed; true } - VirtualKeyCode::W | VirtualKeyCode::Up => { + KeyCode::KeyW | KeyCode::ArrowUp => { self.is_forward_pressed = is_pressed; true } - VirtualKeyCode::A | VirtualKeyCode::Left => { + KeyCode::KeyA | KeyCode::ArrowLeft => { self.is_left_pressed = is_pressed; true } - VirtualKeyCode::S | VirtualKeyCode::Down => { + KeyCode::KeyS | KeyCode::ArrowDown => { self.is_backward_pressed = is_pressed; true } - VirtualKeyCode::D | VirtualKeyCode::Right => { + KeyCode::KeyD | KeyCode::ArrowRight => { self.is_right_pressed = is_pressed; true } diff --git a/cubeway/src/lib.rs b/cubeway/src/lib.rs index 82b83aa..8a5fa8d 100644 --- a/cubeway/src/lib.rs +++ b/cubeway/src/lib.rs @@ -5,9 +5,7 @@ use cube::Cube; use util::rand; use wgpu::{util::DeviceExt, ComputePipeline}; use winit::{ - event::*, - event_loop::{ControlFlow, EventLoop}, - window::{Window, WindowBuilder}, + event::*, event_loop::{ControlFlow, EventLoop}, keyboard::{KeyCode, PhysicalKey}, window::{Window, WindowBuilder} }; #[cfg(target_arch = "wasm32")] @@ -87,8 +85,8 @@ impl Instance { } } -struct State { - surface: wgpu::Surface, +struct State<'a> { + surface: wgpu::Surface<'a>, device: wgpu::Device, queue: wgpu::Queue, config: wgpu::SurfaceConfiguration, @@ -104,15 +102,15 @@ struct State { camera_bind_group: wgpu::BindGroup, instances: Vec, depth_texture: texture::Texture, - window: Window, + window: &'a Window, particle_bind_groups: Vec, particle_buffers: Vec, compute_pipeline: ComputePipeline, } -impl State { - async fn new(window: Window, particle_count: usize) -> Self { +impl<'a> State<'a> { + async fn new(window: &'a Window, particle_count: usize) -> State<'a> { let size = window.inner_size(); // The instance is a handle to our GPU @@ -124,11 +122,7 @@ impl State { gles_minor_version: Default::default(), }); - // # Safety - // - // The surface needs to live as long as the window that created it. - // State owns the window so this should be safe. - let surface = unsafe { instance.create_surface(&window) }.unwrap(); + let surface = instance.create_surface(window).unwrap(); let adapter = instance .request_adapter(&wgpu::RequestAdapterOptions { @@ -143,12 +137,12 @@ impl State { .request_device( &wgpu::DeviceDescriptor { label: None, - features: wgpu::Features::empty(), - limits: if cfg!(target_arch = "wasm32") { + required_limits: if cfg!(target_arch = "wasm32") { wgpu::Limits::downlevel_defaults() } else { wgpu::Limits::default() }, + required_features: wgpu::Features::empty(), }, None, // Trace path ) @@ -174,6 +168,7 @@ impl State { present_mode: surface_caps.present_modes[0], alpha_mode: surface_caps.alpha_modes[0], view_formats: vec![], + desired_maximum_frame_latency: 2, }; surface.configure(&device, &config); @@ -538,12 +533,13 @@ pub fn setup() { #[cfg_attr(target_arch = "wasm32", wasm_bindgen)] pub async fn run(particle_count: usize) { - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = WindowBuilder::new() .with_fullscreen(Some(winit::window::Fullscreen::Borderless(None))) .build(&event_loop) .unwrap(); + #[cfg(target_arch = "wasm32")] { // Winit prevents sizing with CSS, so we have to set @@ -567,57 +563,67 @@ pub async fn run(particle_count: usize) { } // State::new uses async code, so we're going to wait for it to finish - let mut state = State::new(window, particle_count).await; - - event_loop.run(move |event, _, control_flow| { - match event { - Event::WindowEvent { - ref event, - window_id, - } if window_id == state.window().id() => { - if !state.input(event) { - match event { - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - input: - KeyboardInput { - state: ElementState::Pressed, - virtual_keycode: Some(VirtualKeyCode::Escape), - .. - }, - .. - } => *control_flow = ControlFlow::Exit, - WindowEvent::Resized(physical_size) => { - state.resize(*physical_size); - } - WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { - // new_inner_size is &mut so w have to dereference it twice - state.resize(**new_inner_size); + let mut state = State::new(&window, particle_count).await; + let mut surface_configured = false; + + + event_loop + .run(move |event, control_flow| { + match event { + Event::WindowEvent { + ref event, + window_id, + } if window_id == state.window().id() => { + if !state.input(event) { + // UPDATED! + match event { + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + state: ElementState::Pressed, + physical_key: PhysicalKey::Code(KeyCode::Escape), + .. + }, + .. + } => control_flow.exit(), + WindowEvent::Resized(physical_size) => { + log::info!("physical_size: {physical_size:?}"); + surface_configured = true; + state.resize(*physical_size); + } + WindowEvent::RedrawRequested => { + // This tells winit that we want another frame after this one + state.window().request_redraw(); + + if !surface_configured { + return; + } + + state.update(); + match state.render() { + Ok(_) => {} + // Reconfigure the surface if it's lost or outdated + Err( + wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated, + ) => state.resize(state.size), + // The system is out of memory, we should probably quit + Err(wgpu::SurfaceError::OutOfMemory) => { + log::error!("OutOfMemory"); + control_flow.exit(); + } + + // This happens when the a frame takes too long to present + Err(wgpu::SurfaceError::Timeout) => { + log::warn!("Surface timeout") + } + } + } + _ => {} } - _ => {} - } - } - } - Event::RedrawRequested(window_id) if window_id == state.window().id() => { - state.update(); - match state.render() { - Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - state.resize(state.size) } - // The system is out of memory, we should probably quit - Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, - // We're ignoring timeouts - Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"), } + _ => {} } - Event::MainEventsCleared => { - // RedrawRequested will only trigger once, unless we manually - // request it. - state.window().request_redraw(); - } - _ => {} - } - }); + }); }