From 5e9bc64757b4d0613af897b1da092880f6128029 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Fri, 29 Aug 2025 13:33:42 +0200 Subject: [PATCH] vulkan: make mixed device use a non-fatal error --- src/gfx_apis/vulkan.rs | 6 +++- src/gfx_apis/vulkan/image.rs | 5 ++-- src/gfx_apis/vulkan/renderer.rs | 51 +++++++++++++++++---------------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/gfx_apis/vulkan.rs b/src/gfx_apis/vulkan.rs index 4b9282fa..c8295659 100644 --- a/src/gfx_apis/vulkan.rs +++ b/src/gfx_apis/vulkan.rs @@ -210,6 +210,10 @@ pub enum VulkanError { BusyInTransfer, #[error("Driver does not support descriptor buffers")] NoDescriptorBuffer, + #[error("A non-vulkan buffer was passed into the vulkan renderer")] + NonVulkanBuffer, + #[error("Mixed vulkan device use")] + MixedVulkanDeviceUse, } impl From for GfxError { @@ -284,7 +288,7 @@ impl GfxContext for Context { damage: Option<&[Rect]>, ) -> Result, GfxError> { if let Some(old) = old { - let old = (old as Rc).into_vk(&self.0.device.device); + let old = (old as Rc).into_vk(&self.0.device.device)?; let shm = match &old.ty { VulkanImageMemory::DmaBuf(_) => unreachable!(), VulkanImageMemory::Blend(_) => unreachable!(), diff --git a/src/gfx_apis/vulkan/image.rs b/src/gfx_apis/vulkan/image.rs index 09f4bf7a..4216e84e 100644 --- a/src/gfx_apis/vulkan/image.rs +++ b/src/gfx_apis/vulkan/image.rs @@ -556,8 +556,9 @@ impl GfxFramebuffer for VulkanImage { blend_buffer: Option<&Rc>, blend_cd: &Rc, ) -> Result, GfxError> { - let mut blend_buffer = - blend_buffer.map(|b| b.clone().into_vk(&self.renderer.device.device)); + let mut blend_buffer = blend_buffer + .map(|b| b.clone().into_vk(&self.renderer.device.device)) + .transpose()?; if let Some(bb) = &blend_buffer && bb.size() != self.size() { diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index b384af96..fd461e7c 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -627,7 +627,7 @@ impl VulkanRenderer { opts: &[GfxApiOpt], blend_cd: &ColorDescription, fb_cd: &ColorDescription, - ) { + ) -> Result<(), VulkanError> { zone!("convert_ops"); let memory = &mut *self.memory.borrow_mut(); for ops in memory.ops.values_mut() { @@ -744,7 +744,7 @@ impl VulkanRenderer { } } GfxApiOpt::CopyTexture(ct) => { - let tex = ct.tex.clone().into_vk(&self.device.device); + let tex = ct.tex.clone().into_vk(&self.device.device)?; if tex.contents_are_undefined.get() { log::warn!("Ignoring undefined texture"); continue; @@ -815,6 +815,7 @@ impl VulkanRenderer { } } sync(memory); + Ok(()) } fn create_data_buffer(&self) -> Result<(), VulkanError> { @@ -1735,7 +1736,7 @@ impl VulkanRenderer { clear: Option<&Color>, region: &Region, bb: Option<&VulkanImage>, - ) { + ) -> Result<(), VulkanError> { zone!("create_paint_regions"); let memory = &mut *self.memory.borrow_mut(); memory.regions_1.clear(); @@ -1755,7 +1756,7 @@ impl VulkanRenderer { break 'opaque false; } if !c.opaque { - let tex = c.tex.as_vk(&self.device.device); + let tex = c.tex.as_vk(&self.device.device)?; if tex.format.has_alpha { break 'opaque false; } @@ -1848,6 +1849,7 @@ impl VulkanRenderer { }); } } + Ok(()) } fn elide_blend_buffer(&self, blend_buffer: &mut Option>) { @@ -1874,11 +1876,11 @@ impl VulkanRenderer { bb_cd: &Rc, ) -> Result<(), VulkanError> { self.check_defunct()?; - self.create_regions(fb, opts, clear, region, blend_buffer.as_deref()); + self.create_regions(fb, opts, clear, region, blend_buffer.as_deref())?; self.elide_blend_buffer(&mut blend_buffer); let bb = blend_buffer.as_deref(); let buf = self.gfx_command_buffers.allocate()?; - self.convert_ops(opts, bb_cd, fb_cd); + self.convert_ops(opts, bb_cd, fb_cd)?; self.create_data_buffer()?; self.create_uniform_buffer()?; self.collect_memory(); @@ -1956,40 +1958,41 @@ impl Debug for VulkanRenderer { } impl VulkanImage { - fn assert_device(&self, device: &Device) { - assert_eq!( - self.renderer.device.device.handle(), - device.handle(), - "Mixed vulkan device use" - ); + fn assert_device(&self, device: &Device) -> Result<(), VulkanError> { + if self.renderer.device.device.handle() != device.handle() { + return Err(VulkanError::MixedVulkanDeviceUse); + } + Ok(()) } } impl dyn GfxTexture { - fn as_vk(&self, device: &Device) -> &VulkanImage { + fn as_vk(&self, device: &Device) -> Result<&VulkanImage, VulkanError> { let img: &VulkanImage = (self as &dyn Any) .downcast_ref() - .expect("Non-vulkan texture passed into vulkan"); - img.assert_device(device); - img + .ok_or(VulkanError::NonVulkanBuffer)?; + img.assert_device(device)?; + Ok(img) } - pub(super) fn into_vk(self: Rc, device: &Device) -> Rc { + pub(super) fn into_vk(self: Rc, device: &Device) -> Result, VulkanError> { let img: Rc = (self as Rc) .downcast() - .expect("Non-vulkan texture passed into vulkan"); - img.assert_device(device); - img + .ok() + .ok_or(VulkanError::NonVulkanBuffer)?; + img.assert_device(device)?; + Ok(img) } } impl dyn GfxBlendBuffer { - pub(super) fn into_vk(self: Rc, device: &Device) -> Rc { + pub(super) fn into_vk(self: Rc, device: &Device) -> Result, VulkanError> { let img: Rc = (self as Rc) .downcast() - .expect("Non-vulkan blend buffer passed into vulkan"); - img.assert_device(device); - img + .ok() + .ok_or(VulkanError::NonVulkanBuffer)?; + img.assert_device(device)?; + Ok(img) } }