From 2fae64a18c3253a892c9b3e529fb7b09e0bac753 Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Fri, 14 Aug 2026 18:54:33 -0700 Subject: move the Frame destruction code to where it goes this is, however, the first time one of these render state objects has been managed by another one rather than by main() directly, so there's a little weirdness around the lifetime logic that might need reconsidering. seems okay for now though. Force-Push: yes Change-Id: Ide3b9f0a7163f78a51ceed4dfb506232475354dd --- src/graphics/frame.rs | 32 ++++++++++++++++++++++++++++++++ src/graphics/render.rs | 22 +++++----------------- 2 files changed, 37 insertions(+), 17 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/frame.rs b/src/graphics/frame.rs index 721eced..749b5ac 100644 --- a/src/graphics/frame.rs +++ b/src/graphics/frame.rs @@ -77,6 +77,8 @@ impl Frame { texture: &Texture, render_pass: &vk::RenderPass) -> Result<()> { + Frame::destroy_replaceable(frames, permanent); + let device = &permanent.device; let primary_command_pool = &permanent.primary_command_pool; let descriptor_set_layout = &for_reinit.descriptor_set_layout; @@ -116,6 +118,35 @@ impl Frame { Ok(()) } + + // This relies on its caller to have already waited for the device to be + // idle. + #[allow(unsafe_code)] + pub fn destroy(frames: &mut Vec, permanent: &Permanent) { + Frame::destroy_replaceable(frames, permanent); + } + + #[allow(unsafe_code)] + pub fn destroy_replaceable(frames: &mut Vec, permanent: &Permanent) { + let device = &permanent.device; + + let mut command_buffers = Vec::new(); + for frame in frames { + unsafe { device.destroy_framebuffer(frame.framebuffer, None) }; + + command_buffers.push(frame.command_buffer); + } + + // Notice that we free the buffers in the pool, but do not destroy the + // pool itself. Notice also that we only do this for the primary command + // pool, because that's the only one where we've kept track of the + // buffers. We promise ourselves to free buffers in the transient pool + // immediately after using them. + unsafe { + device.free_command_buffers(permanent.primary_command_pool, + &command_buffers) + }; + } } @@ -225,3 +256,4 @@ fn init_descriptor_sets(count: usize, device: &Device, Ok(sets) } + diff --git a/src/graphics/render.rs b/src/graphics/render.rs index 00e55ee..30f4b62 100644 --- a/src/graphics/render.rs +++ b/src/graphics/render.rs @@ -98,6 +98,8 @@ impl Render { pub fn destroy(mut self, permanent: &Permanent) { self.destroy_replaceable(permanent); + Frame::destroy(&mut self.per_frame, permanent); + if let Some(model) = self.model { model.destroy(&permanent.device); } @@ -105,24 +107,10 @@ impl Render { #[allow(unsafe_code)] fn destroy_replaceable(&mut self, permanent: &Permanent) { - let device = &permanent.device; - - let mut command_buffers = Vec::new(); - for frame in &self.per_frame { - unsafe { device.destroy_framebuffer(frame.framebuffer, None) }; + // We skip calling Frame::destroy_replaceable() here because then it would + // be called twice during Render::reinit(), and that seems excessive. - command_buffers.push(frame.command_buffer); - } - - // Notice that we free the buffers in the pool, but do not destroy the - // pool itself. Notice also that we only do this for the primary command - // pool, because that's the only one where we've kept track of the - // buffers. We promise ourselves to free buffers in the transient pool - // immediately after using them. - unsafe { - device.free_command_buffers(permanent.primary_command_pool, - &command_buffers) - }; + let device = &permanent.device; unsafe { device.destroy_pipeline(self.pipeline, None) }; unsafe { device.destroy_pipeline_layout(self.pipeline_layout, None) }; -- cgit 1.4.1