fix swapchain/surface drop logic error
This commit is contained in:
parent
60760ba67f
commit
3c59cf022a
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{borrow::Cow, sync::Arc};
|
use std::{borrow::Cow, mem::ManuallyDrop, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{Allocation, AllocationStrategy, DeviceHandle, DeviceObject, QueueFlags},
|
device::{Allocation, AllocationStrategy, DeviceHandle, DeviceObject, QueueFlags},
|
||||||
|
|
@ -408,7 +408,10 @@ impl Image {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn create_view(self: &Arc<Self>, mut desc: ImageViewDesc) -> crate::Result<ImageView> {
|
pub fn create_view(
|
||||||
|
self: &Arc<Self>,
|
||||||
|
mut desc: ImageViewDesc,
|
||||||
|
) -> crate::Result<ManuallyDrop<ImageView>> {
|
||||||
// validate
|
// validate
|
||||||
if !view_kind_compatible(self.desc.kind, desc.kind) {
|
if !view_kind_compatible(self.desc.kind, desc.kind) {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
|
|
@ -471,11 +474,11 @@ impl Image {
|
||||||
let device = self.image.device();
|
let device = self.image.device();
|
||||||
let view = unsafe { device.raw.create_image_view(&create_info, None)? };
|
let view = unsafe { device.raw.create_image_view(&create_info, None)? };
|
||||||
|
|
||||||
Ok(ImageView {
|
Ok(ManuallyDrop::new(ImageView {
|
||||||
view: DeviceObject::new(view, device.clone(), desc.name.clone()),
|
view: DeviceObject::new(view, device.clone(), desc.name.clone()),
|
||||||
desc,
|
desc,
|
||||||
image: self.clone(),
|
image: self.clone(),
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
mem::ManuallyDrop,
|
||||||
num::NonZero,
|
num::NonZero,
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
sync::{
|
sync::{
|
||||||
|
|
@ -21,6 +22,7 @@ use crate::{
|
||||||
device::{Device, DeviceObject},
|
device::{Device, DeviceObject},
|
||||||
images::{self, ImageViewDesc},
|
images::{self, ImageViewDesc},
|
||||||
sync::Fence,
|
sync::Fence,
|
||||||
|
util::DropGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
use derive_more::Debug;
|
use derive_more::Debug;
|
||||||
|
|
@ -30,16 +32,12 @@ pub struct Surface {
|
||||||
pub(crate) raw: vk::SurfaceKHR,
|
pub(crate) raw: vk::SurfaceKHR,
|
||||||
#[debug(skip)]
|
#[debug(skip)]
|
||||||
pub(crate) functor: khr::surface::Instance,
|
pub(crate) functor: khr::surface::Instance,
|
||||||
pub(crate) instance: Instance,
|
|
||||||
pub(crate) swapchain: RwLock<Option<Arc<Swapchain>>>,
|
pub(crate) swapchain: RwLock<Option<Arc<Swapchain>>>,
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Surface {
|
// destroy surface after any fields that depend on it
|
||||||
fn drop(&mut self) {
|
_drop_guard: DropGuard,
|
||||||
unsafe {
|
// drop reference to instance after destroying the surface
|
||||||
self.functor.destroy_surface(self.raw, None);
|
pub(crate) instance: Instance,
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Surface {
|
impl Surface {
|
||||||
|
|
@ -82,9 +80,18 @@ impl Surface {
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
raw,
|
raw,
|
||||||
functor,
|
|
||||||
swapchain: RwLock::new(None),
|
swapchain: RwLock::new(None),
|
||||||
instance: instance.clone(),
|
instance: instance.clone(),
|
||||||
|
|
||||||
|
// the surface must be destroyed after the swapchain
|
||||||
|
_drop_guard: DropGuard::new({
|
||||||
|
let functor = functor.clone();
|
||||||
|
move || {
|
||||||
|
functor.destroy_surface(raw, None);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
functor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,9 +124,18 @@ impl Surface {
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
raw,
|
raw,
|
||||||
functor,
|
|
||||||
swapchain: RwLock::new(None),
|
swapchain: RwLock::new(None),
|
||||||
instance: instance.clone(),
|
instance: instance.clone(),
|
||||||
|
|
||||||
|
// the surface must be destroyed after the swapchain
|
||||||
|
_drop_guard: DropGuard::new({
|
||||||
|
let functor = functor.clone();
|
||||||
|
move || unsafe {
|
||||||
|
functor.destroy_surface(raw, None);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
functor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,7 +587,7 @@ impl Swapchain {
|
||||||
SwapchainImage {
|
SwapchainImage {
|
||||||
index: idx as u32,
|
index: idx as u32,
|
||||||
swapchain: self,
|
swapchain: self,
|
||||||
view,
|
view: ManuallyDrop::into_inner(view),
|
||||||
acquire,
|
acquire,
|
||||||
release,
|
release,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
mem::ManuallyDrop,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -76,6 +77,23 @@ pub(crate) mod weak_vec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(derive_more::Debug)]
|
||||||
|
pub(crate) struct DropGuard(#[debug(skip)] ManuallyDrop<Box<dyn FnOnce()>>);
|
||||||
|
|
||||||
|
impl DropGuard {
|
||||||
|
pub(crate) fn new(f: impl FnOnce() + 'static) -> Self {
|
||||||
|
Self(ManuallyDrop::new(Box::new(f)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for DropGuard {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
ManuallyDrop::take(&mut self.0)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct DebugName {
|
pub struct DebugName {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue