summary refs log tree commit diff
path: root/src/graphics_window_dressing.rs
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-07-09 17:41:09 -0700
committerIrene Knapp <ireneista@irenes.space>2026-07-09 17:41:09 -0700
commite547dc5ab4ec1667bcde6368f756f63123eae587 (patch)
tree925ce9406b80e8e1567b631f4ef228520b9d34a4 /src/graphics_window_dressing.rs
parent05982c6344ec308bcd60fae9457979a20ff18bc8 (diff)
okay, reinitializing for window changes works now
yay

Force-Push: yes
Change-Id: Id8dce4cd4bc696be322fe5b612837e3651437f7e
Diffstat (limited to 'src/graphics_window_dressing.rs')
-rw-r--r--src/graphics_window_dressing.rs117
1 files changed, 92 insertions, 25 deletions
diff --git a/src/graphics_window_dressing.rs b/src/graphics_window_dressing.rs
index e35332f..63fc693 100644
--- a/src/graphics_window_dressing.rs
+++ b/src/graphics_window_dressing.rs
@@ -1,6 +1,8 @@
 #![deny(unsafe_code)]
 use crate::error::*;
-use crate::graphics_permanent::{ PermanentGraphicsState, QueueFamilyIndices };
+use crate::graphics_permanent::{
+  PermanentGraphicsState, GraphicsStateForReinit, QueueFamilyIndices
+};
 
 use std::collections::BTreeSet;
 use vulkanalia::{ Device, Instance };
@@ -73,14 +75,15 @@ pub struct Concurrency {
 
 impl WindowDressing {
   pub fn new(permanent: &PermanentGraphicsState,
-             physical_device: vk::PhysicalDevice,
-             indices: QueueFamilyIndices)
+             for_reinit: &GraphicsStateForReinit)
       -> Result<Self>
   {
     let window = &permanent.window;
     let instance = &permanent.instance;
     let surface = &permanent.surface;
     let device = &permanent.device;
+    let physical_device = &for_reinit.physical_device;
+    let indices = &for_reinit.indices;
 
     let swapchain = init_swapchain(
             window, instance, surface, &physical_device, device, &indices)?;
@@ -93,9 +96,10 @@ impl WindowDressing {
     let framebuffers = init_framebuffers(
             device, &swapchain.extent, &swapchain.image_views, &render_pass)?;
 
-    let (command_pool, command_buffers)
-            = init_commands(device, &swapchain.extent, &framebuffers,
-                            &render_pass, &pipeline, &indices)?;
+    let command_pool = init_command_pool(device, indices)?;
+    let command_buffers = init_commands(device, &swapchain.extent,
+                                        &framebuffers, &render_pass,
+                                        &pipeline, &command_pool)?;
 
     let concurrency = init_concurrency(device, &swapchain.images)?;
 
@@ -111,9 +115,58 @@ impl WindowDressing {
     })
   }
 
+
   #[allow(unsafe_code)]
-  pub fn destroy(self, permanent: &PermanentGraphicsState) {
+  pub fn reinit(&mut self, permanent: &PermanentGraphicsState,
+                for_reinit: &GraphicsStateForReinit)
+      -> Result<()>
+  {
+    let window = &permanent.window;
+    let instance = &permanent.instance;
+    let surface = &permanent.surface;
     let device = &permanent.device;
+    let physical_device = &for_reinit.physical_device;
+    let indices = &for_reinit.indices;
+
+    unsafe { device.device_wait_idle() }.unwrap();
+
+    self.destroy_replaceable(device);
+
+    let swapchain = init_swapchain(
+            window, instance, surface, &physical_device, device, &indices)?;
+
+    let render_pass = init_render_pass(device, &swapchain.format)?;
+
+    let (pipeline_layout, pipeline)
+            = init_pipeline(device, &swapchain.extent, &render_pass)?;
+
+    let framebuffers = init_framebuffers(
+            device, &swapchain.extent, &swapchain.image_views, &render_pass)?;
+
+    // Notice that we reused the command pool.
+    let command_buffers = init_commands(
+            device, &swapchain.extent, &framebuffers, &render_pass,
+            &pipeline, &self.command_pool)?;
+
+    self.concurrency.image_fences.resize(swapchain.images.len(),
+                                         vk::Fence::null());
+
+    self.swapchain = swapchain;
+    self.render_pass = render_pass;
+    self.pipeline = pipeline;
+    self.pipeline_layout = pipeline_layout;
+    self.framebuffers = framebuffers;
+    self.command_buffers = command_buffers;
+
+    Ok(())
+  }
+
+
+  //   This relies on its caller to have already waited for the device to be
+  // idle.
+  #[allow(unsafe_code)]
+  pub fn destroy(mut self, device: &Device) {
+    self.destroy_replaceable(device);
 
     for semaphore in self.concurrency.image_available_semaphores {
       unsafe { device.destroy_semaphore(semaphore, None) };
@@ -127,18 +180,28 @@ impl WindowDressing {
       unsafe { device.destroy_fence(fence, None) };
     }
 
+    // Notice that destroy_replaceable freed the pool, but did not destroy it.
     unsafe { device.destroy_command_pool(self.command_pool, None) };
+  }
 
-    for framebuffer in self.framebuffers {
-      unsafe { device.destroy_framebuffer(framebuffer, None) };
+
+  #[allow(unsafe_code)]
+  fn destroy_replaceable(&mut self, device: &Device) {
+    for framebuffer in &self.framebuffers {
+      unsafe { device.destroy_framebuffer(*framebuffer, None) };
     }
 
+    // Notice that we free the pool, but do not destroy it.
+    unsafe {
+      device.free_command_buffers(self.command_pool, &self.command_buffers)
+    };
+
     unsafe { device.destroy_pipeline(self.pipeline, None) };
-    unsafe { device.destroy_render_pass(self.render_pass, None) };
     unsafe { device.destroy_pipeline_layout(self.pipeline_layout, None) };
+    unsafe { device.destroy_render_pass(self.render_pass, None) };
 
-    for view in self.swapchain.image_views {
-      unsafe { device.destroy_image_view(view, None) };
+    for view in &self.swapchain.image_views {
+      unsafe { device.destroy_image_view(*view, None) };
     }
 
     unsafe { device.destroy_swapchain_khr(self.swapchain.swapchain, None) };
@@ -446,27 +509,31 @@ fn init_framebuffers(device: &Device, extent: &vk::Extent2D,
 
 
 #[allow(unsafe_code)]
-fn init_commands(device: &Device,
-                 extent: &vk::Extent2D,
-                 framebuffers: &Vec<vk::Framebuffer>,
-                 render_pass: &vk::RenderPass,
-                 pipeline: &vk::Pipeline,
-                 indices: &QueueFamilyIndices)
-    -> Result<(vk::CommandPool, Vec<vk::CommandBuffer>)>
+fn init_command_pool(device: &Device, indices: &QueueFamilyIndices)
+    -> Result<vk::CommandPool>
 {
-  // We call this one last time. It's kind of a problem.
-
   let command_pool_info = vk::CommandPoolCreateInfo::builder()
                               .flags(vk::CommandPoolCreateFlags::empty())
                               .queue_family_index(indices.graphics);
 
-  let command_pool = unsafe {
+  Ok(unsafe {
     device.create_command_pool(&command_pool_info, None)
-  }?;
+  }?)
+}
+
 
+#[allow(unsafe_code)]
+fn init_commands(device: &Device,
+                 extent: &vk::Extent2D,
+                 framebuffers: &Vec<vk::Framebuffer>,
+                 render_pass: &vk::RenderPass,
+                 pipeline: &vk::Pipeline,
+                 command_pool: &vk::CommandPool)
+    -> Result<Vec<vk::CommandBuffer>>
+{
   let command_buffer_allocation_info
           = vk::CommandBufferAllocateInfo::builder()
-                .command_pool(command_pool)
+                .command_pool(*command_pool)
                 .level(vk::CommandBufferLevel::PRIMARY)
                 .command_buffer_count(framebuffers.len() as u32);
   let command_buffers = unsafe {
@@ -523,7 +590,7 @@ fn init_commands(device: &Device,
     unsafe { device.end_command_buffer(command_buffer) }?;
   }
 
-  Ok((command_pool, command_buffers))
+  Ok(command_buffers)
 }