1
0
Fork 0
forked from wry/wry

Merge pull request #254 from mahkoh/jorth/vulkan-limits

vulkan: don't try to export non-exportable images
This commit is contained in:
mahkoh 2024-09-05 10:18:00 +02:00 committed by GitHub
commit 1bacaa7b02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 68 additions and 61 deletions

View file

@ -718,19 +718,21 @@ fn validate_modifier(
return false; return false;
} }
} }
let Some(max_extents) = modifier.transfer_max_extents else { let Some(limits) = modifier.transfer_limits else {
return false; return false;
}; };
let mut max_width = max_extents.width; let mut max_width = limits.max_width;
let mut max_height = max_extents.height; let mut max_height = limits.max_height;
let mut exportable = limits.exportable;
if usage.contains(BO_USE_RENDERING) { if usage.contains(BO_USE_RENDERING) {
let Some(max_extents) = modifier.render_max_extents else { let Some(limits) = modifier.render_limits else {
return false; return false;
}; };
max_width = max_width.min(max_extents.width); max_width = max_width.min(limits.max_width);
max_height = max_height.min(max_extents.height); 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; return false;
} }
true true

View file

@ -262,8 +262,8 @@ impl VulkanInstance {
let mut supports_rendering = false; let mut supports_rendering = false;
let mut supports_texturing = false; let mut supports_texturing = false;
f.modifiers.values().for_each(|v| { f.modifiers.values().for_each(|v| {
supports_rendering |= v.render_max_extents.is_some(); supports_rendering |= v.render_limits.is_some();
supports_texturing |= v.texture_max_extents.is_some(); supports_texturing |= v.texture_limits.is_some();
}); });
supports_rendering && supports_texturing supports_rendering && supports_texturing
}) })

View file

@ -32,21 +32,22 @@ pub struct VulkanModifier {
pub modifier: Modifier, pub modifier: Modifier,
pub planes: usize, pub planes: usize,
pub features: FormatFeatureFlags, pub features: FormatFeatureFlags,
pub render_max_extents: Option<VulkanMaxExtents>, pub render_limits: Option<VulkanModifierLimits>,
pub texture_max_extents: Option<VulkanMaxExtents>, pub texture_limits: Option<VulkanModifierLimits>,
pub transfer_max_extents: Option<VulkanMaxExtents>, pub transfer_limits: Option<VulkanModifierLimits>,
pub render_needs_bridge: bool, pub render_needs_bridge: bool,
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct VulkanMaxExtents { pub struct VulkanModifierLimits {
pub width: u32, pub max_width: u32,
pub height: u32, pub max_height: u32,
pub exportable: bool,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct VulkanInternalFormat { pub struct VulkanInternalFormat {
pub max_extents: VulkanMaxExtents, pub limits: VulkanModifierLimits,
} }
const FRAMEBUFFER_FEATURES: FormatFeatureFlags = FormatFeatureFlags::from_raw( const FRAMEBUFFER_FEATURES: FormatFeatureFlags = FormatFeatureFlags::from_raw(
@ -168,9 +169,10 @@ impl VulkanInstance {
}; };
} }
Ok(Some(VulkanInternalFormat { Ok(Some(VulkanInternalFormat {
max_extents: VulkanMaxExtents { limits: VulkanModifierLimits {
width: format_properties.image_format_properties.max_extent.width, max_width: format_properties.image_format_properties.max_extent.width,
height: format_properties.image_format_properties.max_extent.height, max_height: format_properties.image_format_properties.max_extent.height,
exportable: false,
}, },
})) }))
} }
@ -201,16 +203,16 @@ impl VulkanInstance {
}; };
let mut mods = AHashMap::new(); let mut mods = AHashMap::new();
for modifier in drm_mods { for modifier in drm_mods {
let mut render_max_extents = self.get_max_extents( let mut render_limits = self.get_max_extents(
phy_dev, phy_dev,
format, format,
FRAMEBUFFER_FEATURES, FRAMEBUFFER_FEATURES,
FRAMEBUFFER_USAGE, FRAMEBUFFER_USAGE,
&modifier, &modifier,
)?; )?;
let texture_max_extents = let texture_limits =
self.get_max_extents(phy_dev, format, TEX_FEATURES, TEX_USAGE, &modifier)?; 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, phy_dev,
format, format,
TRANSFER_FEATURES, TRANSFER_FEATURES,
@ -218,14 +220,14 @@ impl VulkanInstance {
&modifier, &modifier,
)?; )?;
let mut render_needs_bridge = false; let mut render_needs_bridge = false;
if render_max_extents.is_none() && modifier.drm_format_modifier == LINEAR_MODIFIER { if render_limits.is_none() && modifier.drm_format_modifier == LINEAR_MODIFIER {
render_max_extents = self.get_fb_bridged_max_extents( render_limits = self.get_fb_bridged_max_extents(
phy_dev, phy_dev,
format, format,
internal_format_properties, internal_format_properties,
&modifier, &modifier,
)?; )?;
if render_max_extents.is_some() { if render_limits.is_some() {
render_needs_bridge = true; render_needs_bridge = true;
} }
} }
@ -235,9 +237,9 @@ impl VulkanInstance {
modifier: modifier.drm_format_modifier, modifier: modifier.drm_format_modifier,
planes: modifier.drm_format_modifier_plane_count as _, planes: modifier.drm_format_modifier_plane_count as _,
features: modifier.drm_format_modifier_tiling_features, features: modifier.drm_format_modifier_tiling_features,
render_max_extents, render_limits,
texture_max_extents, texture_limits,
transfer_max_extents, transfer_limits,
render_needs_bridge, render_needs_bridge,
}, },
); );
@ -251,7 +253,7 @@ impl VulkanInstance {
format: &Format, format: &Format,
internal_format_properties: &FormatProperties, internal_format_properties: &FormatProperties,
modifier: &DrmFormatModifierPropertiesEXT, modifier: &DrmFormatModifierPropertiesEXT,
) -> Result<Option<VulkanMaxExtents>, VulkanError> { ) -> Result<Option<VulkanModifierLimits>, VulkanError> {
let transfer_dst_max_extents = self.get_max_extents( let transfer_dst_max_extents = self.get_max_extents(
phy_dev, phy_dev,
format, format,
@ -272,15 +274,16 @@ impl VulkanInstance {
let Some(bridge_format) = bridge_format else { let Some(bridge_format) = bridge_format else {
return Ok(None); return Ok(None);
}; };
Ok(Some(VulkanMaxExtents { Ok(Some(VulkanModifierLimits {
width: min( max_width: min(
transfer_dst_max_extents.width, transfer_dst_max_extents.max_width,
bridge_format.max_extents.width, bridge_format.limits.max_width,
), ),
height: min( max_height: min(
transfer_dst_max_extents.height, transfer_dst_max_extents.max_height,
bridge_format.max_extents.height, bridge_format.limits.max_height,
), ),
exportable: transfer_dst_max_extents.exportable,
})) }))
} }
@ -291,7 +294,7 @@ impl VulkanInstance {
features: FormatFeatureFlags, features: FormatFeatureFlags,
usage: ImageUsageFlags, usage: ImageUsageFlags,
props: &DrmFormatModifierPropertiesEXT, props: &DrmFormatModifierPropertiesEXT,
) -> Result<Option<VulkanMaxExtents>, VulkanError> { ) -> Result<Option<VulkanModifierLimits>, VulkanError> {
if !props.drm_format_modifier_tiling_features.contains(features) { if !props.drm_format_modifier_tiling_features.contains(features) {
return Ok(None); return Ok(None);
} }
@ -327,17 +330,19 @@ impl VulkanInstance {
}; };
} }
let image_format_props = &image_format_props.image_format_properties; 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_properties
.external_memory_features .external_memory_features;
.contains(ExternalMemoryFeatureFlags::IMPORTABLE); let importable = external_memory_features.contains(ExternalMemoryFeatureFlags::IMPORTABLE);
if !importable { if !importable {
return Ok(None); return Ok(None);
} }
let exportable = external_memory_features.contains(ExternalMemoryFeatureFlags::EXPORTABLE);
Ok(Some(VulkanMaxExtents { Ok(Some(VulkanModifierLimits {
width: image_format_props.max_extent.width, max_width: image_format_props.max_extent.width,
height: image_format_props.max_extent.height, max_height: image_format_props.max_extent.height,
exportable,
})) }))
} }
} }

View file

@ -3,7 +3,7 @@ use {
format::Format, format::Format,
gfx_api::{GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, SyncFile}, gfx_api::{GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, SyncFile},
gfx_apis::vulkan::{ gfx_apis::vulkan::{
allocator::VulkanAllocation, device::VulkanDevice, format::VulkanMaxExtents, allocator::VulkanAllocation, device::VulkanDevice, format::VulkanModifierLimits,
renderer::VulkanRenderer, shm_image::VulkanShmImage, util::OnDrop, VulkanError, renderer::VulkanRenderer, shm_image::VulkanShmImage, util::OnDrop, VulkanError,
}, },
theme::Color, theme::Color,
@ -36,8 +36,8 @@ pub struct VulkanDmaBufImageTemplate {
pub(super) height: u32, pub(super) height: u32,
pub(super) disjoint: bool, pub(super) disjoint: bool,
pub(super) dmabuf: DmaBuf, pub(super) dmabuf: DmaBuf,
pub(super) render_max_extents: Option<VulkanMaxExtents>, pub(super) render_limits: Option<VulkanModifierLimits>,
pub(super) texture_max_extents: Option<VulkanMaxExtents>, pub(super) texture_limits: Option<VulkanModifierLimits>,
pub(super) render_needs_bridge: bool, pub(super) render_needs_bridge: bool,
} }
@ -124,16 +124,16 @@ impl VulkanRenderer {
} }
let width = dmabuf.width as u32; let width = dmabuf.width as u32;
let height = dmabuf.height 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, 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, 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 !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::ModifierUseNotSupported);
} }
return Err(VulkanError::ImageTooLarge); return Err(VulkanError::ImageTooLarge);
@ -151,8 +151,8 @@ impl VulkanRenderer {
height, height,
disjoint, disjoint,
dmabuf: dmabuf.clone(), dmabuf: dmabuf.clone(),
render_max_extents: modifier.render_max_extents, render_limits: modifier.render_limits,
texture_max_extents: modifier.texture_max_extents, texture_limits: modifier.texture_limits,
render_needs_bridge: modifier.render_needs_bridge, render_needs_bridge: modifier.render_needs_bridge,
})) }))
} }
@ -201,12 +201,12 @@ impl VulkanDmaBufImageTemplate {
fn create_image(self: &Rc<Self>, for_rendering: bool) -> Result<Rc<VulkanImage>, VulkanError> { fn create_image(self: &Rc<Self>, for_rendering: bool) -> Result<Rc<VulkanImage>, VulkanError> {
let device = &self.renderer.device; let device = &self.renderer.device;
let max_extents = match for_rendering { let limits = match for_rendering {
true => self.render_max_extents, true => self.render_limits,
false => self.texture_max_extents, false => self.texture_limits,
}; };
let max_extents = max_extents.ok_or(VulkanError::ModifierUseNotSupported)?; let limits = limits.ok_or(VulkanError::ModifierUseNotSupported)?;
if self.width > max_extents.width || self.height > max_extents.height { if self.width > limits.max_width || self.height > limits.max_height {
return Err(VulkanError::ImageTooLarge); return Err(VulkanError::ImageTooLarge);
} }
let image = { let image = {

View file

@ -151,13 +151,13 @@ impl VulkanDevice {
read_modifiers: vk read_modifiers: vk
.modifiers .modifiers
.values() .values()
.filter(|m| m.texture_max_extents.is_some()) .filter(|m| m.texture_limits.is_some())
.map(|m| m.modifier) .map(|m| m.modifier)
.collect(), .collect(),
write_modifiers: vk write_modifiers: vk
.modifiers .modifiers
.values() .values()
.filter(|m| m.render_max_extents.is_some()) .filter(|m| m.render_limits.is_some())
.map(|m| m.modifier) .map(|m| m.modifier)
.collect(), .collect(),
}, },

View file

@ -280,7 +280,7 @@ impl VulkanRenderer {
.get(&format.drm) .get(&format.drm)
.ok_or(VulkanError::FormatNotSupported)?; .ok_or(VulkanError::FormatNotSupported)?;
let shm = vk_format.shm.as_ref().ok_or(VulkanError::ShmNotSupported)?; 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); return Err(VulkanError::ImageTooLarge);
} }
let size = stride.checked_mul(height).ok_or(VulkanError::ShmOverflow)?; let size = stride.checked_mul(height).ok_or(VulkanError::ShmOverflow)?;