fix(vulkan-smoke): make teardown order explicit
This commit is contained in:
@@ -1621,36 +1621,39 @@ impl VulkanSmokeRenderer {
|
|||||||
if let Some(resources) = self.swapchain_resources.take() {
|
if let Some(resources) = self.swapchain_resources.take() {
|
||||||
destroy_swapchain_resources(device, self.command_pool, resources);
|
destroy_swapchain_resources(device, self.command_pool, resources);
|
||||||
}
|
}
|
||||||
}
|
self.images_in_flight.clear();
|
||||||
|
self.current_frame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for VulkanSmokeRenderer {
|
fn teardown(&mut self) {
|
||||||
fn drop(&mut self) {
|
if let Some(device) = self.device.as_ref() {
|
||||||
|
// SAFETY: The logical device remains live until teardown finishes and idling prevents in-flight work from touching swapchain, buffers, sync objects or the command pool after destruction starts.
|
||||||
|
let _ = unsafe { device.device().device_wait_idle() };
|
||||||
|
}
|
||||||
self.destroy_swapchain_resources();
|
self.destroy_swapchain_resources();
|
||||||
if let Some(device) = self.device.as_ref() {
|
if let Some(device) = self.device.as_ref() {
|
||||||
if let Some(buffer) = self.index_buffer.take() {
|
if let Some(buffer) = self.index_buffer.take() {
|
||||||
// SAFETY: Buffer and memory belong to this device and are destroyed once.
|
// SAFETY: Buffer and memory belong to this device and are destroyed once after the device has been idled and frame work has been torn down.
|
||||||
unsafe {
|
unsafe {
|
||||||
device.device().destroy_buffer(buffer.buffer, None);
|
device.device().destroy_buffer(buffer.buffer, None);
|
||||||
device.device().free_memory(buffer.memory, None);
|
device.device().free_memory(buffer.memory, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(buffer) = self.vertex_buffer.take() {
|
if let Some(buffer) = self.vertex_buffer.take() {
|
||||||
// SAFETY: Buffer and memory belong to this device and are destroyed once.
|
// SAFETY: Buffer and memory belong to this device and are destroyed once after the device has been idled and frame work has been torn down.
|
||||||
unsafe {
|
unsafe {
|
||||||
device.device().destroy_buffer(buffer.buffer, None);
|
device.device().destroy_buffer(buffer.buffer, None);
|
||||||
device.device().free_memory(buffer.memory, None);
|
device.device().free_memory(buffer.memory, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SAFETY: The command pool belongs to this device and is destroyed once after buffers are freed.
|
// SAFETY: The command pool belongs to this device and is destroyed once after the device is idle and all command buffers allocated from it were freed above.
|
||||||
unsafe {
|
unsafe {
|
||||||
device
|
device
|
||||||
.device()
|
.device()
|
||||||
.destroy_command_pool(self.command_pool, None);
|
.destroy_command_pool(self.command_pool, None);
|
||||||
};
|
};
|
||||||
// SAFETY: The logical device remains live until the renderer completes teardown.
|
|
||||||
let _ = unsafe { device.device().device_wait_idle() };
|
|
||||||
}
|
}
|
||||||
|
// Drop child Vulkan owners explicitly before their parents instead of relying on field order.
|
||||||
self.swapchain.take();
|
self.swapchain.take();
|
||||||
self.device.take();
|
self.device.take();
|
||||||
self.surface.take();
|
self.surface.take();
|
||||||
@@ -1659,6 +1662,12 @@ impl Drop for VulkanSmokeRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for VulkanSmokeRenderer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn create_validation_messenger(
|
fn create_validation_messenger(
|
||||||
instance: &VulkanInstanceProbe,
|
instance: &VulkanInstanceProbe,
|
||||||
) -> Result<VulkanValidationMessenger, VulkanSmokeRendererError> {
|
) -> Result<VulkanValidationMessenger, VulkanSmokeRendererError> {
|
||||||
|
|||||||
Reference in New Issue
Block a user