1
0
Fork 0
forked from wry/wry

vulkan: prevent creating new async processes after the renderer has been dropped

This commit is contained in:
Julian Orth 2024-09-06 18:35:48 +02:00
parent cf74756c34
commit 1f169a0d7b
3 changed files with 14 additions and 0 deletions

View file

@ -197,6 +197,8 @@ pub enum VulkanError {
WaitIdle(#[source] vk::Result), WaitIdle(#[source] vk::Result),
#[error("Could not dup a DRM device")] #[error("Could not dup a DRM device")]
DupDrm(#[source] DrmError), DupDrm(#[source] DrmError),
#[error("Graphics context has already been dropped")]
Defunct,
} }
impl From<VulkanError> for GfxError { impl From<VulkanError> for GfxError {

View file

@ -78,6 +78,7 @@ pub struct VulkanRenderer {
pub(super) tex_frag_mult_opaque_shader: Rc<VulkanShader>, pub(super) tex_frag_mult_opaque_shader: Rc<VulkanShader>,
pub(super) tex_frag_mult_alpha_shader: Rc<VulkanShader>, pub(super) tex_frag_mult_alpha_shader: Rc<VulkanShader>,
pub(super) tex_descriptor_set_layout: Rc<VulkanDescriptorSetLayout>, pub(super) tex_descriptor_set_layout: Rc<VulkanDescriptorSetLayout>,
pub(super) defunct: Cell<bool>,
} }
pub(super) struct UsedTexture { pub(super) struct UsedTexture {
@ -195,6 +196,7 @@ impl VulkanDevice {
tex_frag_mult_opaque_shader, tex_frag_mult_opaque_shader,
tex_frag_mult_alpha_shader, tex_frag_mult_alpha_shader,
tex_descriptor_set_layout, tex_descriptor_set_layout,
defunct: Cell::new(false),
}); });
render.get_or_create_pipelines(XRGB8888.vk_format)?; render.get_or_create_pipelines(XRGB8888.vk_format)?;
Ok(render) Ok(render)
@ -996,6 +998,7 @@ impl VulkanRenderer {
opts: &[GfxApiOpt], opts: &[GfxApiOpt],
clear: Option<&Color>, clear: Option<&Color>,
) -> Result<(), VulkanError> { ) -> Result<(), VulkanError> {
self.check_defunct()?;
let buf = self.allocate_command_buffer()?; let buf = self.allocate_command_buffer()?;
self.collect_memory(opts); self.collect_memory(opts);
self.begin_command_buffer(buf.buffer)?; self.begin_command_buffer(buf.buffer)?;
@ -1025,6 +1028,7 @@ impl VulkanRenderer {
} }
pub fn on_drop(&self) { pub fn on_drop(&self) {
self.defunct.set(true);
let mut pending_frames = self.pending_frames.lock(); let mut pending_frames = self.pending_frames.lock();
let mut pending_uploads = self.pending_uploads.lock(); let mut pending_uploads = self.pending_uploads.lock();
if pending_frames.is_not_empty() || pending_uploads.is_not_empty() { if pending_frames.is_not_empty() || pending_uploads.is_not_empty() {
@ -1037,6 +1041,13 @@ impl VulkanRenderer {
pending_frames.clear(); pending_frames.clear();
pending_uploads.clear(); pending_uploads.clear();
} }
pub(super) fn check_defunct(&self) -> Result<(), VulkanError> {
match self.defunct.get() {
true => Err(VulkanError::Defunct),
false => Ok(()),
}
}
} }
impl Debug for VulkanRenderer { impl Debug for VulkanRenderer {

View file

@ -41,6 +41,7 @@ impl VulkanShmImage {
buffer: &[Cell<u8>], buffer: &[Cell<u8>],
damage: Option<&[Rect]>, damage: Option<&[Rect]>,
) -> Result<(), VulkanError> { ) -> Result<(), VulkanError> {
img.renderer.check_defunct()?;
if let Some(damage) = damage { if let Some(damage) = damage {
if damage.is_empty() { if damage.is_empty() {
return Ok(()); return Ok(());