From e547dc5ab4ec1667bcde6368f756f63123eae587 Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Thu, 9 Jul 2026 17:41:09 -0700 Subject: okay, reinitializing for window changes works now yay Force-Push: yes Change-Id: Id8dce4cd4bc696be322fe5b612837e3651437f7e --- src/main.rs | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 12 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 5dea456..9beb151 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ #![deny(unsafe_code)] use crate::error::*; -use crate::graphics_permanent::PermanentGraphicsState; +use crate::graphics_permanent::{ + PermanentGraphicsState, GraphicsStateForReinit +}; use crate::graphics_window_dressing::{ WindowDressing, N_SIMULTANEOUS_FRAMES }; @@ -20,7 +22,9 @@ mod graphics_window_dressing; struct Surreality { permanent: RefCell>, + for_reinit: RefCell>, window_dressing: RefCell>, + is_reinit_queued: bool, frame_index: usize, } @@ -28,28 +32,56 @@ impl Surreality { fn new() -> Self { Surreality { permanent: RefCell::new(None), + for_reinit: RefCell::new(None), window_dressing: RefCell::new(None), + is_reinit_queued: false, frame_index: 0, } } #[allow(unsafe_code)] fn init(&mut self, event_loop: &ActiveEventLoop) -> Result<()> { - let (permanent, physical_device, indices, enable_swapchain) - = PermanentGraphicsState::new(event_loop)?; + let (permanent, for_reinit, enable_swapchain) + = PermanentGraphicsState::new(event_loop)?; if enable_swapchain.0 { *self.window_dressing.get_mut() - = Some(WindowDressing::new(&permanent, physical_device, indices)?); + = Some(WindowDressing::new(&permanent, &for_reinit)?); } *self.permanent.get_mut() = Some(permanent); + *self.for_reinit.get_mut() = Some(for_reinit); + + Ok(()) + } + + fn reinit(&mut self) -> Result<()> { + if let Some(permanent) = self.permanent.borrow().as_ref() + && let Some(for_reinit) = self.for_reinit.borrow().as_ref() + && let Some(window_dressing) + = self.window_dressing.borrow_mut().as_mut() + { + window_dressing.reinit(permanent, for_reinit)?; + } + + Ok(()) + } + + + fn do_frame(&mut self, window_id: WindowId) -> Result<()> { + if self.render(window_id)? || self.is_reinit_queued { + self.is_reinit_queued = false; + + self.reinit()?; + } Ok(()) } + // This returns true if, and only if, the window dressing should be + // reinitialized. #[allow(unsafe_code)] - fn render(&mut self, window_id: WindowId) -> Result<()> { + fn render(&mut self, window_id: WindowId) -> Result { if let Some(permanent) = self.permanent.borrow().as_ref() && let Some(window_dressing) = self.window_dressing.borrow_mut().as_mut() @@ -66,11 +98,15 @@ impl Surreality { unsafe { device.wait_for_fences(&[*frame_fence], true, u64::MAX) }?; - let image_index = unsafe { + let image_index = match unsafe { device.acquire_next_image_khr(window_dressing.swapchain.swapchain, u64::MAX, *image_available_semaphore, vk::Fence::null()) - }?.0 as usize; + } { + Ok((image_index, _)) => image_index as usize, + Err(vk::ErrorCode::OUT_OF_DATE_KHR) => return Ok(true), + Err(e) => return Err(Error::from(e)), + }; let image_fence = &concurrency.image_fences[image_index]; if !image_fence.is_null() { @@ -103,14 +139,19 @@ impl Surreality { .swapchains(&swapchains) .image_indices(&image_indices); - unsafe { + match unsafe { device.queue_present_khr(permanent.presentation_queue, &present_info) - }?; + } { + Ok(vk::SuccessCode::SUBOPTIMAL_KHR) => return Ok(true), + Err(vk::ErrorCode::OUT_OF_DATE_KHR) => return Ok(true), + Err(e) => return Err(Error::from(e)), + Ok(_) => (), + } self.frame_index = (frame_index + 1) % N_SIMULTANEOUS_FRAMES; } - Ok(()) + Ok(false) } } @@ -121,7 +162,7 @@ impl Drop for Surreality { unsafe { permanent.device.device_wait_idle() }.unwrap(); if let Some(window_dressing) = self.window_dressing.replace(None) { - window_dressing.destroy(&permanent); + window_dressing.destroy(&permanent.device); } permanent.destroy(); @@ -145,14 +186,23 @@ impl ApplicationHandler for Surreality { match event { WindowEvent::RedrawRequested => { if !event_loop.exiting() { - if let Err(e) = self.render(window_id) { + if let Err(e) = self.do_frame(window_id) { eprintln!("Error: {}", e); } } } + WindowEvent::CloseRequested => { event_loop.exit(); } + + WindowEvent::Resized(_) => { + self.is_reinit_queued = true; + if let Err(e) = self.do_frame(window_id) { + eprintln!("Error: {}", e); + } + } + _ => { } } } -- cgit 1.4.1