fix(vulkan): capture shutdown validation after owner drop

This commit is contained in:
2026-07-03 16:55:19 +04:00
parent 8a8ef614f2
commit 29bf4830cf
+21 -26
View File
@@ -31,28 +31,20 @@ fn take_runtime_owners_in_dependency_order<Instance, Validation, Surface, Device
instance.take(); instance.take();
} }
fn take_runtime_owners_with_validation_snapshot< fn take_runtime_children_with_validation_snapshot<Surface, Device, Swapchain, Validation, Snapshot, Capture>(
Instance,
Validation,
Surface,
Device,
Swapchain,
Snapshot,
Capture,
>(
instance: &mut Option<Instance>,
validation: &mut Option<Validation>,
surface: &mut Option<Surface>, surface: &mut Option<Surface>,
device: &mut Option<Device>, device: &mut Option<Device>,
swapchain: &mut Option<Swapchain>, swapchain: &mut Option<Swapchain>,
validation: &Option<Validation>,
capture: Capture, capture: Capture,
) -> Option<Snapshot> ) -> Option<Snapshot>
where where
Capture: FnOnce(&Validation) -> Snapshot, Capture: FnOnce(&Validation) -> Snapshot,
{ {
let snapshot = validation.as_ref().map(capture); swapchain.take();
take_runtime_owners_in_dependency_order(instance, validation, surface, device, swapchain); device.take();
snapshot surface.take();
validation.as_ref().map(capture)
} }
struct RollbackOnDrop<T, F> struct RollbackOnDrop<T, F>
@@ -668,15 +660,16 @@ impl VulkanSmokeRenderer {
})?; })?;
} }
self.destroy_device_owned_resources(); self.destroy_device_owned_resources();
let validation = take_runtime_owners_with_validation_snapshot( let validation = take_runtime_children_with_validation_snapshot(
&mut self.instance,
&mut self.validation,
&mut self.surface, &mut self.surface,
&mut self.device, &mut self.device,
&mut self.swapchain, &mut self.swapchain,
&self.validation,
VulkanValidationMessenger::report, VulkanValidationMessenger::report,
) )
.unwrap_or_default(); .unwrap_or_default();
self.validation.take();
self.instance.take();
Ok(VulkanSmokeShutdownReport { Ok(VulkanSmokeShutdownReport {
renderer_report: self.report.clone(), renderer_report: self.report.clone(),
swapchain_recreate_count: self.swapchain_recreate_count, swapchain_recreate_count: self.swapchain_recreate_count,
@@ -690,14 +683,15 @@ impl VulkanSmokeRenderer {
let _ = unsafe { device.device().device_wait_idle() }; let _ = unsafe { device.device().device_wait_idle() };
} }
self.destroy_device_owned_resources(); self.destroy_device_owned_resources();
let _ = take_runtime_owners_with_validation_snapshot( let _ = take_runtime_children_with_validation_snapshot(
&mut self.instance,
&mut self.validation,
&mut self.surface, &mut self.surface,
&mut self.device, &mut self.device,
&mut self.swapchain, &mut self.swapchain,
&self.validation,
VulkanValidationMessenger::report, VulkanValidationMessenger::report,
); );
self.validation.take();
self.instance.take();
} }
} }
@@ -710,7 +704,7 @@ impl Drop for VulkanSmokeRenderer {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{ use super::{
take_runtime_owners_in_dependency_order, take_runtime_owners_with_validation_snapshot, take_runtime_children_with_validation_snapshot, take_runtime_owners_in_dependency_order,
RollbackOnDrop, RollbackOnDrop,
}; };
use std::cell::RefCell; use std::cell::RefCell;
@@ -850,7 +844,7 @@ mod tests {
} }
#[test] #[test]
fn final_validation_snapshot_is_captured_before_validation_drop() { fn final_validation_snapshot_is_captured_after_surface_device_swapchain_drop() {
let log = Rc::new(RefCell::new(Vec::new())); let log = Rc::new(RefCell::new(Vec::new()));
let mut instance = Some(tracker(TeardownStep::Instance, &log)); let mut instance = Some(tracker(TeardownStep::Instance, &log));
let mut validation = Some(tracker(TeardownStep::Validation, &log)); let mut validation = Some(tracker(TeardownStep::Validation, &log));
@@ -858,17 +852,18 @@ mod tests {
let mut device = Some(tracker(TeardownStep::Device, &log)); let mut device = Some(tracker(TeardownStep::Device, &log));
let mut swapchain = Some(tracker(TeardownStep::Swapchain, &log)); let mut swapchain = Some(tracker(TeardownStep::Swapchain, &log));
let snapshot = take_runtime_owners_with_validation_snapshot( let snapshot = take_runtime_children_with_validation_snapshot(
&mut instance,
&mut validation,
&mut surface, &mut surface,
&mut device, &mut device,
&mut swapchain, &mut swapchain,
&validation,
|_| { |_| {
log.borrow_mut().push(TeardownStep::Snapshot); log.borrow_mut().push(TeardownStep::Snapshot);
TeardownStep::Validation TeardownStep::Validation
}, },
); );
validation.take();
instance.take();
assert_eq!(snapshot, Some(TeardownStep::Validation)); assert_eq!(snapshot, Some(TeardownStep::Validation));
assert_eq!( assert_eq!(
@@ -876,10 +871,10 @@ mod tests {
.expect("all drop trackers released") .expect("all drop trackers released")
.into_inner(), .into_inner(),
vec![ vec![
TeardownStep::Snapshot,
TeardownStep::Swapchain, TeardownStep::Swapchain,
TeardownStep::Device, TeardownStep::Device,
TeardownStep::Surface, TeardownStep::Surface,
TeardownStep::Snapshot,
TeardownStep::Validation, TeardownStep::Validation,
TeardownStep::Instance, TeardownStep::Instance,
] ]