From 591867ffbd8da4b7f20a51d95b36560986e0e945 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 5 Sep 2024 10:15:31 +0200 Subject: [PATCH] vulkan: don't try to export non-exportable images --- src/gfx_apis/vulkan/bo_allocator.rs | 16 ++++--- src/gfx_apis/vulkan/device.rs | 4 +- src/gfx_apis/vulkan/format.rs | 73 +++++++++++++++-------------- src/gfx_apis/vulkan/image.rs | 30 ++++++------ src/gfx_apis/vulkan/renderer.rs | 4 +- src/gfx_apis/vulkan/shm_image.rs | 2 +- 6 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/gfx_apis/vulkan/bo_allocator.rs b/src/gfx_apis/vulkan/bo_allocator.rs index 0ac35f9a..1874c72f 100644 --- a/src/gfx_apis/vulkan/bo_allocator.rs +++ b/src/gfx_apis/vulkan/bo_allocator.rs @@ -718,19 +718,21 @@ fn validate_modifier( return false; } } - let Some(max_extents) = modifier.transfer_max_extents else { + let Some(limits) = modifier.transfer_limits else { return false; }; - let mut max_width = max_extents.width; - let mut max_height = max_extents.height; + let mut max_width = limits.max_width; + let mut max_height = limits.max_height; + let mut exportable = limits.exportable; if usage.contains(BO_USE_RENDERING) { - let Some(max_extents) = modifier.render_max_extents else { + let Some(limits) = modifier.render_limits else { return false; }; - max_width = max_width.min(max_extents.width); - max_height = max_height.min(max_extents.height); + max_width = max_width.min(limits.max_width); + max_height = max_height.min(limits.max_height); + exportable &= limits.exportable; } - if width > max_width || height > max_height { + if !exportable || width > max_width || height > max_height { return false; } true diff --git a/src/gfx_apis/vulkan/device.rs b/src/gfx_apis/vulkan/device.rs index 33706e7b..8e23fabe 100644 --- a/src/gfx_apis/vulkan/device.rs +++ b/src/gfx_apis/vulkan/device.rs @@ -262,8 +262,8 @@ impl VulkanInstance { let mut supports_rendering = false; let mut supports_texturing = false; f.modifiers.values().for_each(|v| { - supports_rendering |= v.render_max_extents.is_some(); - supports_texturing |= v.texture_max_extents.is_some(); + supports_rendering |= v.render_limits.is_some(); + supports_texturing |= v.texture_limits.is_some(); }); supports_rendering && supports_texturing }) diff --git a/src/gfx_apis/vulkan/format.rs b/src/gfx_apis/vulkan/format.rs index 03cda4f5..e565ecab 100644 --- a/src/gfx_apis/vulkan/format.rs +++ b/src/gfx_apis/vulkan/format.rs @@ -32,21 +32,22 @@ pub struct VulkanModifier { pub modifier: Modifier, pub planes: usize, pub features: FormatFeatureFlags, - pub render_max_extents: Option, - pub texture_max_extents: Option, - pub transfer_max_extents: Option, + pub render_limits: Option, + pub texture_limits: Option, + pub transfer_limits: Option, pub render_needs_bridge: bool, } #[derive(Copy, Clone, Debug)] -pub struct VulkanMaxExtents { - pub width: u32, - pub height: u32, +pub struct VulkanModifierLimits { + pub max_width: u32, + pub max_height: u32, + pub exportable: bool, } #[derive(Debug)] pub struct VulkanInternalFormat { - pub max_extents: VulkanMaxExtents, + pub limits: VulkanModifierLimits, } const FRAMEBUFFER_FEATURES: FormatFeatureFlags = FormatFeatureFlags::from_raw( @@ -168,9 +169,10 @@ impl VulkanInstance { }; } Ok(Some(VulkanInternalFormat { - max_extents: VulkanMaxExtents { - width: format_properties.image_format_properties.max_extent.width, - height: format_properties.image_format_properties.max_extent.height, + limits: VulkanModifierLimits { + max_width: format_properties.image_format_properties.max_extent.width, + max_height: format_properties.image_format_properties.max_extent.height, + exportable: false, }, })) } @@ -201,16 +203,16 @@ impl VulkanInstance { }; let mut mods = AHashMap::new(); for modifier in drm_mods { - let mut render_max_extents = self.get_max_extents( + let mut render_limits = self.get_max_extents( phy_dev, format, FRAMEBUFFER_FEATURES, FRAMEBUFFER_USAGE, &modifier, )?; - let texture_max_extents = + let texture_limits = self.get_max_extents(phy_dev, format, TEX_FEATURES, TEX_USAGE, &modifier)?; - let transfer_max_extents = self.get_max_extents( + let transfer_limits = self.get_max_extents( phy_dev, format, TRANSFER_FEATURES, @@ -218,14 +220,14 @@ impl VulkanInstance { &modifier, )?; let mut render_needs_bridge = false; - if render_max_extents.is_none() && modifier.drm_format_modifier == LINEAR_MODIFIER { - render_max_extents = self.get_fb_bridged_max_extents( + if render_limits.is_none() && modifier.drm_format_modifier == LINEAR_MODIFIER { + render_limits = self.get_fb_bridged_max_extents( phy_dev, format, internal_format_properties, &modifier, )?; - if render_max_extents.is_some() { + if render_limits.is_some() { render_needs_bridge = true; } } @@ -235,9 +237,9 @@ impl VulkanInstance { modifier: modifier.drm_format_modifier, planes: modifier.drm_format_modifier_plane_count as _, features: modifier.drm_format_modifier_tiling_features, - render_max_extents, - texture_max_extents, - transfer_max_extents, + render_limits, + texture_limits, + transfer_limits, render_needs_bridge, }, ); @@ -251,7 +253,7 @@ impl VulkanInstance { format: &Format, internal_format_properties: &FormatProperties, modifier: &DrmFormatModifierPropertiesEXT, - ) -> Result, VulkanError> { + ) -> Result, VulkanError> { let transfer_dst_max_extents = self.get_max_extents( phy_dev, format, @@ -272,15 +274,16 @@ impl VulkanInstance { let Some(bridge_format) = bridge_format else { return Ok(None); }; - Ok(Some(VulkanMaxExtents { - width: min( - transfer_dst_max_extents.width, - bridge_format.max_extents.width, + Ok(Some(VulkanModifierLimits { + max_width: min( + transfer_dst_max_extents.max_width, + bridge_format.limits.max_width, ), - height: min( - transfer_dst_max_extents.height, - bridge_format.max_extents.height, + max_height: min( + transfer_dst_max_extents.max_height, + bridge_format.limits.max_height, ), + exportable: transfer_dst_max_extents.exportable, })) } @@ -291,7 +294,7 @@ impl VulkanInstance { features: FormatFeatureFlags, usage: ImageUsageFlags, props: &DrmFormatModifierPropertiesEXT, - ) -> Result, VulkanError> { + ) -> Result, VulkanError> { if !props.drm_format_modifier_tiling_features.contains(features) { return Ok(None); } @@ -327,17 +330,19 @@ impl VulkanInstance { }; } let image_format_props = &image_format_props.image_format_properties; - let importable = external_image_format_props + let external_memory_features = &external_image_format_props .external_memory_properties - .external_memory_features - .contains(ExternalMemoryFeatureFlags::IMPORTABLE); + .external_memory_features; + let importable = external_memory_features.contains(ExternalMemoryFeatureFlags::IMPORTABLE); if !importable { return Ok(None); } + let exportable = external_memory_features.contains(ExternalMemoryFeatureFlags::EXPORTABLE); - Ok(Some(VulkanMaxExtents { - width: image_format_props.max_extent.width, - height: image_format_props.max_extent.height, + Ok(Some(VulkanModifierLimits { + max_width: image_format_props.max_extent.width, + max_height: image_format_props.max_extent.height, + exportable, })) } } diff --git a/src/gfx_apis/vulkan/image.rs b/src/gfx_apis/vulkan/image.rs index bd638574..d92ad53a 100644 --- a/src/gfx_apis/vulkan/image.rs +++ b/src/gfx_apis/vulkan/image.rs @@ -3,7 +3,7 @@ use { format::Format, gfx_api::{GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, SyncFile}, gfx_apis::vulkan::{ - allocator::VulkanAllocation, device::VulkanDevice, format::VulkanMaxExtents, + allocator::VulkanAllocation, device::VulkanDevice, format::VulkanModifierLimits, renderer::VulkanRenderer, shm_image::VulkanShmImage, util::OnDrop, VulkanError, }, theme::Color, @@ -36,8 +36,8 @@ pub struct VulkanDmaBufImageTemplate { pub(super) height: u32, pub(super) disjoint: bool, pub(super) dmabuf: DmaBuf, - pub(super) render_max_extents: Option, - pub(super) texture_max_extents: Option, + pub(super) render_limits: Option, + pub(super) texture_limits: Option, pub(super) render_needs_bridge: bool, } @@ -124,16 +124,16 @@ impl VulkanRenderer { } let width = dmabuf.width as u32; let height = dmabuf.height as u32; - let can_render = match &modifier.render_max_extents { + let can_render = match &modifier.render_limits { None => false, - Some(t) => width <= t.width && height <= t.height, + Some(t) => width <= t.max_width && height <= t.max_height, }; - let can_texture = match &modifier.texture_max_extents { + let can_texture = match &modifier.texture_limits { None => false, - Some(t) => width <= t.width && height <= t.height, + Some(t) => width <= t.max_width && height <= t.max_height, }; if !can_render && !can_texture { - if modifier.render_max_extents.is_none() && modifier.texture_max_extents.is_none() { + if modifier.render_limits.is_none() && modifier.texture_limits.is_none() { return Err(VulkanError::ModifierUseNotSupported); } return Err(VulkanError::ImageTooLarge); @@ -151,8 +151,8 @@ impl VulkanRenderer { height, disjoint, dmabuf: dmabuf.clone(), - render_max_extents: modifier.render_max_extents, - texture_max_extents: modifier.texture_max_extents, + render_limits: modifier.render_limits, + texture_limits: modifier.texture_limits, render_needs_bridge: modifier.render_needs_bridge, })) } @@ -201,12 +201,12 @@ impl VulkanDmaBufImageTemplate { fn create_image(self: &Rc, for_rendering: bool) -> Result, VulkanError> { let device = &self.renderer.device; - let max_extents = match for_rendering { - true => self.render_max_extents, - false => self.texture_max_extents, + let limits = match for_rendering { + true => self.render_limits, + false => self.texture_limits, }; - let max_extents = max_extents.ok_or(VulkanError::ModifierUseNotSupported)?; - if self.width > max_extents.width || self.height > max_extents.height { + let limits = limits.ok_or(VulkanError::ModifierUseNotSupported)?; + if self.width > limits.max_width || self.height > limits.max_height { return Err(VulkanError::ImageTooLarge); } let image = { diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index 53868dee..834b5d26 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -151,13 +151,13 @@ impl VulkanDevice { read_modifiers: vk .modifiers .values() - .filter(|m| m.texture_max_extents.is_some()) + .filter(|m| m.texture_limits.is_some()) .map(|m| m.modifier) .collect(), write_modifiers: vk .modifiers .values() - .filter(|m| m.render_max_extents.is_some()) + .filter(|m| m.render_limits.is_some()) .map(|m| m.modifier) .collect(), }, diff --git a/src/gfx_apis/vulkan/shm_image.rs b/src/gfx_apis/vulkan/shm_image.rs index b80cf390..e272eb87 100644 --- a/src/gfx_apis/vulkan/shm_image.rs +++ b/src/gfx_apis/vulkan/shm_image.rs @@ -280,7 +280,7 @@ impl VulkanRenderer { .get(&format.drm) .ok_or(VulkanError::FormatNotSupported)?; let shm = vk_format.shm.as_ref().ok_or(VulkanError::ShmNotSupported)?; - if width > shm.max_extents.width || height > shm.max_extents.height { + if width > shm.limits.max_width || height > shm.limits.max_height { return Err(VulkanError::ImageTooLarge); } let size = stride.checked_mul(height).ok_or(VulkanError::ShmOverflow)?;