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;
}
}
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

View file

@ -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
})

View file

@ -32,21 +32,22 @@ pub struct VulkanModifier {
pub modifier: Modifier,
pub planes: usize,
pub features: FormatFeatureFlags,
pub render_max_extents: Option<VulkanMaxExtents>,
pub texture_max_extents: Option<VulkanMaxExtents>,
pub transfer_max_extents: Option<VulkanMaxExtents>,
pub render_limits: Option<VulkanModifierLimits>,
pub texture_limits: Option<VulkanModifierLimits>,
pub transfer_limits: Option<VulkanModifierLimits>,
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<Option<VulkanMaxExtents>, VulkanError> {
) -> Result<Option<VulkanModifierLimits>, 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<Option<VulkanMaxExtents>, VulkanError> {
) -> Result<Option<VulkanModifierLimits>, 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,
}))
}
}

View file

@ -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<VulkanMaxExtents>,
pub(super) texture_max_extents: Option<VulkanMaxExtents>,
pub(super) render_limits: Option<VulkanModifierLimits>,
pub(super) texture_limits: Option<VulkanModifierLimits>,
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<Self>, for_rendering: bool) -> Result<Rc<VulkanImage>, 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 = {

View file

@ -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(),
},

View file

@ -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)?;