mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Fix unnecessarily strict validation for DRM format modifiers (#2469)
This commit is contained in:
parent
c90c6e87c4
commit
4eb8111055
@ -13,6 +13,8 @@ use super::{
|
|||||||
ImageSubresourceLayers, ImageSubresourceRange, ImageTiling, ImageUsage, SampleCount,
|
ImageSubresourceLayers, ImageSubresourceRange, ImageTiling, ImageUsage, SampleCount,
|
||||||
SparseImageMemoryRequirements, SubresourceLayout,
|
SparseImageMemoryRequirements, SubresourceLayout,
|
||||||
};
|
};
|
||||||
|
#[cfg(doc)]
|
||||||
|
use crate::format::DrmFormatModifierProperties;
|
||||||
use crate::{
|
use crate::{
|
||||||
cache::OnceCache,
|
cache::OnceCache,
|
||||||
device::{Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
@ -158,52 +160,53 @@ impl RawImage {
|
|||||||
let format_list_view_formats_vk: Vec<_>;
|
let format_list_view_formats_vk: Vec<_>;
|
||||||
let mut stencil_usage_info_vk = None;
|
let mut stencil_usage_info_vk = None;
|
||||||
|
|
||||||
#[allow(clippy::comparison_chain)]
|
if !drm_format_modifiers.is_empty() {
|
||||||
if drm_format_modifiers.len() == 1 {
|
if drm_format_modifier_plane_layouts.is_empty() {
|
||||||
drm_format_modifier_plane_layouts_vk = drm_format_modifier_plane_layouts
|
let next = drm_format_modifier_list_info_vk.insert(
|
||||||
.iter()
|
ash::vk::ImageDrmFormatModifierListCreateInfoEXT {
|
||||||
.map(|subresource_layout| {
|
drm_format_modifier_count: drm_format_modifiers.len() as u32,
|
||||||
let &SubresourceLayout {
|
p_drm_format_modifiers: drm_format_modifiers.as_ptr(),
|
||||||
offset,
|
..Default::default()
|
||||||
size,
|
},
|
||||||
row_pitch,
|
);
|
||||||
array_pitch,
|
|
||||||
depth_pitch,
|
|
||||||
} = subresource_layout;
|
|
||||||
|
|
||||||
ash::vk::SubresourceLayout {
|
next.p_next = create_info_vk.p_next;
|
||||||
offset,
|
create_info_vk.p_next = next as *const _ as *const _;
|
||||||
size,
|
} else {
|
||||||
row_pitch,
|
drm_format_modifier_plane_layouts_vk = drm_format_modifier_plane_layouts
|
||||||
array_pitch: array_pitch.unwrap_or(0),
|
.iter()
|
||||||
depth_pitch: depth_pitch.unwrap_or(0),
|
.map(|subresource_layout| {
|
||||||
}
|
let &SubresourceLayout {
|
||||||
})
|
offset,
|
||||||
.collect();
|
size,
|
||||||
|
row_pitch,
|
||||||
|
array_pitch,
|
||||||
|
depth_pitch,
|
||||||
|
} = subresource_layout;
|
||||||
|
|
||||||
let next = drm_format_modifier_explicit_info_vk.insert(
|
ash::vk::SubresourceLayout {
|
||||||
ash::vk::ImageDrmFormatModifierExplicitCreateInfoEXT {
|
offset,
|
||||||
drm_format_modifier: drm_format_modifiers[0],
|
size,
|
||||||
drm_format_modifier_plane_count: drm_format_modifier_plane_layouts_vk.len()
|
row_pitch,
|
||||||
as u32,
|
array_pitch: array_pitch.unwrap_or(0),
|
||||||
p_plane_layouts: drm_format_modifier_plane_layouts_vk.as_ptr(),
|
depth_pitch: depth_pitch.unwrap_or(0),
|
||||||
..Default::default()
|
}
|
||||||
},
|
})
|
||||||
);
|
.collect();
|
||||||
|
|
||||||
next.p_next = create_info_vk.p_next;
|
let next = drm_format_modifier_explicit_info_vk.insert(
|
||||||
create_info_vk.p_next = next as *const _ as *const _;
|
ash::vk::ImageDrmFormatModifierExplicitCreateInfoEXT {
|
||||||
} else if drm_format_modifiers.len() > 1 {
|
drm_format_modifier: drm_format_modifiers[0],
|
||||||
let next = drm_format_modifier_list_info_vk.insert(
|
drm_format_modifier_plane_count: drm_format_modifier_plane_layouts_vk.len()
|
||||||
ash::vk::ImageDrmFormatModifierListCreateInfoEXT {
|
as u32,
|
||||||
drm_format_modifier_count: drm_format_modifiers.len() as u32,
|
p_plane_layouts: drm_format_modifier_plane_layouts_vk.as_ptr(),
|
||||||
p_drm_format_modifiers: drm_format_modifiers.as_ptr(),
|
..Default::default()
|
||||||
..Default::default()
|
},
|
||||||
},
|
);
|
||||||
);
|
|
||||||
|
|
||||||
next.p_next = create_info_vk.p_next;
|
next.p_next = create_info_vk.p_next;
|
||||||
create_info_vk.p_next = next as *const _ as *const _;
|
create_info_vk.p_next = next as *const _ as *const _;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !external_memory_handle_types.is_empty() {
|
if !external_memory_handle_types.is_empty() {
|
||||||
@ -1808,29 +1811,36 @@ pub struct ImageCreateInfo {
|
|||||||
/// The default value is [`ImageLayout::Undefined`].
|
/// The default value is [`ImageLayout::Undefined`].
|
||||||
pub initial_layout: ImageLayout,
|
pub initial_layout: ImageLayout,
|
||||||
|
|
||||||
/// The Linux DRM format modifiers that the image should be created with.
|
/// A list of possible Linux DRM format modifiers that the image may be created with. If
|
||||||
|
/// `tiling` is [`ImageTiling::DrmFormatModifier`], then at least one DRM format modifier must
|
||||||
|
/// be provided. Otherwise, this must be empty.
|
||||||
///
|
///
|
||||||
/// If this is not empty, then the
|
/// If more than one DRM format modifier is provided, then the Vulkan driver will choose the
|
||||||
/// [`ext_image_drm_format_modifier`](crate::device::DeviceExtensions::ext_image_drm_format_modifier)
|
/// modifier in an implementation-defined manner. You can query the modifier that has been
|
||||||
/// extension must be enabled on the device.
|
/// chosen, after creating the image, by calling [`Image::drm_format_modifier`].
|
||||||
|
///
|
||||||
|
/// If exactly one DRM format modifier is provided, the image will always be created with that
|
||||||
|
/// modifier. You can then optionally specify the subresource layout of each memory plane with
|
||||||
|
/// the `drm_format_modifier_plane_layouts` field.
|
||||||
///
|
///
|
||||||
/// The default value is empty.
|
/// The default value is empty.
|
||||||
pub drm_format_modifiers: Vec<u64>,
|
pub drm_format_modifiers: Vec<u64>,
|
||||||
|
|
||||||
/// If `drm_format_modifiers` contains one element, provides the subresource layouts of each
|
/// If `drm_format_modifiers` contains exactly one element, optionally specifies an explicit
|
||||||
/// memory plane of the image. The number of elements must equal
|
/// subresource layout for each memory plane of the image.
|
||||||
/// [`DrmFormatModifierProperties::drm_format_modifier_plane_count`], and the following
|
///
|
||||||
/// additional requirements apply to each element:
|
/// If not empty, the number of provided subresource layouts must equal the number of memory
|
||||||
|
/// planes for `drm_format_modifiers[0]`, as reported by
|
||||||
|
/// [`DrmFormatModifierProperties::drm_format_modifier_plane_count`]. The following additional
|
||||||
|
/// requirements apply to each element:
|
||||||
/// - [`SubresourceLayout::size`] must always be 0.
|
/// - [`SubresourceLayout::size`] must always be 0.
|
||||||
/// - If `array_layers` is 1, then [`SubresourceLayout::array_pitch`] must be `None`.
|
/// - If `array_layers` is 1, then [`SubresourceLayout::array_pitch`] must be `None`.
|
||||||
/// - If `image_type` is not [`ImageType::Dim3d`] or `extent[2]` is 1, then
|
/// - If `image_type` is not [`ImageType::Dim3d`] or `extent[2]` is 1, then
|
||||||
/// [`SubresourceLayout::depth_pitch`] must be `None`.
|
/// [`SubresourceLayout::depth_pitch`] must be `None`.
|
||||||
///
|
///
|
||||||
/// If `drm_format_modifiers` does not contain one element, then this must be empty.
|
/// If `drm_format_modifiers` does not contain exactly one element, then this must be empty.
|
||||||
///
|
///
|
||||||
/// The default value is empty.
|
/// The default value is empty.
|
||||||
///
|
|
||||||
/// [`DrmFormatModifierProperties::drm_format_modifier_plane_count`]: crate::format::DrmFormatModifierProperties::drm_format_modifier_plane_count
|
|
||||||
pub drm_format_modifier_plane_layouts: Vec<SubresourceLayout>,
|
pub drm_format_modifier_plane_layouts: Vec<SubresourceLayout>,
|
||||||
|
|
||||||
/// The external memory handle types that are going to be used with the image.
|
/// The external memory handle types that are going to be used with the image.
|
||||||
@ -2683,137 +2693,133 @@ impl ImageCreateInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !drm_format_modifiers.is_empty() {
|
if !(drm_format_modifier_plane_layouts.is_empty() || drm_format_modifiers.len() == 1) {
|
||||||
// This implicitly checks for the enabled extension too,
|
return Err(Box::new(ValidationError {
|
||||||
// so no need to check that separately.
|
problem: "`drm_format_modifier_plane_layouts` is not empty, but \
|
||||||
if tiling != ImageTiling::DrmFormatModifier {
|
`drm_format_modifiers` does not contain exactly one element"
|
||||||
return Err(Box::new(ValidationError {
|
.into(),
|
||||||
problem: "`drm_format_modifiers` is not empty, but \
|
..Default::default()
|
||||||
`tiling` is not `ImageTiling::DrmFormatModifier`"
|
}));
|
||||||
.into(),
|
}
|
||||||
vuids: &["VUID-VkImageCreateInfo-pNext-02262"],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.intersects(ImageCreateFlags::MUTABLE_FORMAT) && view_formats.is_empty() {
|
match (tiling, !drm_format_modifiers.is_empty()) {
|
||||||
return Err(Box::new(ValidationError {
|
(ImageTiling::DrmFormatModifier, true) => {
|
||||||
problem: "`tiling` is `ImageTiling::DrmFormatModifier`, and \
|
if flags.intersects(ImageCreateFlags::MUTABLE_FORMAT) && view_formats.is_empty() {
|
||||||
`flags` contains `ImageCreateFlags::MUTABLE_FORMAT`, but \
|
|
||||||
`view_formats` is empty"
|
|
||||||
.into(),
|
|
||||||
vuids: &["VUID-VkImageCreateInfo-tiling-02353"],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if drm_format_modifiers.len() == 1 {
|
|
||||||
let drm_format_modifier = drm_format_modifiers[0];
|
|
||||||
let drm_format_modifier_properties = format_properties
|
|
||||||
.drm_format_modifier_properties
|
|
||||||
.iter()
|
|
||||||
.find(|properties| properties.drm_format_modifier == drm_format_modifier)
|
|
||||||
.ok_or_else(|| Box::new(ValidationError {
|
|
||||||
problem: "`drm_format_modifiers` has a length of 1, but \
|
|
||||||
`drm_format_modifiers[0]` is not one of the modifiers in \
|
|
||||||
`FormatProperties::drm_format_properties`, as returned by \
|
|
||||||
`PhysicalDevice::format_properties` for `format`".into(),
|
|
||||||
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-drmFormatModifierPlaneCount-02265"],
|
|
||||||
..Default::default()
|
|
||||||
}))?;
|
|
||||||
|
|
||||||
if drm_format_modifier_plane_layouts.len()
|
|
||||||
!= drm_format_modifier_properties.drm_format_modifier_plane_count as usize
|
|
||||||
{
|
|
||||||
return Err(Box::new(ValidationError {
|
return Err(Box::new(ValidationError {
|
||||||
problem: "`drm_format_modifiers` has a length of 1, but the length of \
|
problem: "`tiling` is `ImageTiling::DrmFormatModifier`, and \
|
||||||
`drm_format_modifiers_plane_layouts` does not \
|
`flags` contains `ImageCreateFlags::MUTABLE_FORMAT`, but \
|
||||||
equal `DrmFormatModifierProperties::drm_format_modifier_plane_count` \
|
`view_formats` is empty"
|
||||||
for `drm_format_modifiers[0]`, as returned by \
|
.into(),
|
||||||
`PhysicalDevice::format_properties` for `format`".into(),
|
vuids: &["VUID-VkImageCreateInfo-tiling-02353"],
|
||||||
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-drmFormatModifierPlaneCount-02265"],
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (index, subresource_layout) in
|
|
||||||
drm_format_modifier_plane_layouts.iter().enumerate()
|
|
||||||
{
|
|
||||||
let &SubresourceLayout {
|
|
||||||
offset: _,
|
|
||||||
size,
|
|
||||||
row_pitch: _,
|
|
||||||
array_pitch,
|
|
||||||
depth_pitch,
|
|
||||||
} = subresource_layout;
|
|
||||||
|
|
||||||
if size != 0 {
|
|
||||||
return Err(Box::new(ValidationError {
|
|
||||||
context: format!("drm_format_modifier_plane_layouts[{}].size", index)
|
|
||||||
.into(),
|
|
||||||
problem: "is not zero".into(),
|
|
||||||
vuids: &[
|
|
||||||
"VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-size-02267",
|
|
||||||
],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if array_layers == 1 && array_pitch.is_some() {
|
|
||||||
return Err(Box::new(ValidationError {
|
|
||||||
problem: format!(
|
|
||||||
"`array_layers` is 1, but \
|
|
||||||
`drm_format_modifier_plane_layouts[{}].array_pitch` is `Some`",
|
|
||||||
index
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-arrayPitch-02268"],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if extent[2] == 1 && depth_pitch.is_some() {
|
|
||||||
return Err(Box::new(ValidationError {
|
|
||||||
problem: format!(
|
|
||||||
"`extent[2]` is 1, but \
|
|
||||||
`drm_format_modifier_plane_layouts[{}].depth_pitch` is `Some`",
|
|
||||||
index
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-depthPitch-02269"],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !drm_format_modifier_plane_layouts.is_empty() {
|
if !drm_format_modifier_plane_layouts.is_empty() {
|
||||||
return Err(Box::new(ValidationError {
|
let drm_format_modifier = drm_format_modifiers[0];
|
||||||
problem: "`drm_format_modifiers` does not contain one element, but \
|
let drm_format_modifier_properties = format_properties
|
||||||
`drm_format_modifier_plane_layouts` is not empty"
|
.drm_format_modifier_properties
|
||||||
.into(),
|
.iter()
|
||||||
..Default::default()
|
.find(|properties| properties.drm_format_modifier == drm_format_modifier)
|
||||||
}));
|
.ok_or_else(|| Box::new(ValidationError {
|
||||||
|
problem: "`drm_format_modifier_plane_layouts` is not empty, but \
|
||||||
|
`drm_format_modifiers[0]` is not one of the modifiers in \
|
||||||
|
`FormatProperties::drm_format_properties`, as returned by \
|
||||||
|
`PhysicalDevice::format_properties` for `format`".into(),
|
||||||
|
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-drmFormatModifierPlaneCount-02265"],
|
||||||
|
..Default::default()
|
||||||
|
}))?;
|
||||||
|
|
||||||
|
if drm_format_modifier_plane_layouts.len()
|
||||||
|
!= drm_format_modifier_properties.drm_format_modifier_plane_count as usize
|
||||||
|
{
|
||||||
|
return Err(Box::new(ValidationError {
|
||||||
|
problem: "`drm_format_modifier_plane_layouts` is not empty, but the \
|
||||||
|
number of provided subresource layouts does not equal the number \
|
||||||
|
of memory planes for `drm_format_modifiers[0]`, specified in \
|
||||||
|
`DrmFormatModifierProperties::drm_format_modifier_plane_count`, \
|
||||||
|
as returned by `PhysicalDevice::format_properties` for `format`"
|
||||||
|
.into(),
|
||||||
|
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-drmFormatModifierPlaneCount-02265"],
|
||||||
|
..Default::default()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index, subresource_layout) in
|
||||||
|
drm_format_modifier_plane_layouts.iter().enumerate()
|
||||||
|
{
|
||||||
|
let &SubresourceLayout {
|
||||||
|
offset: _,
|
||||||
|
size,
|
||||||
|
row_pitch: _,
|
||||||
|
array_pitch,
|
||||||
|
depth_pitch,
|
||||||
|
} = subresource_layout;
|
||||||
|
|
||||||
|
if size != 0 {
|
||||||
|
return Err(Box::new(ValidationError {
|
||||||
|
context: format!(
|
||||||
|
"drm_format_modifier_plane_layouts[{}].size",
|
||||||
|
index
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
problem: "is not zero".into(),
|
||||||
|
vuids: &[
|
||||||
|
"VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-size-02267",
|
||||||
|
],
|
||||||
|
..Default::default()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if array_layers == 1 && array_pitch.is_some() {
|
||||||
|
return Err(Box::new(ValidationError {
|
||||||
|
problem: format!(
|
||||||
|
"`array_layers` is 1, but \
|
||||||
|
`drm_format_modifier_plane_layouts[{}].array_pitch` is `Some`",
|
||||||
|
index
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-arrayPitch-02268"],
|
||||||
|
..Default::default()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if extent[2] == 1 && depth_pitch.is_some() {
|
||||||
|
return Err(Box::new(ValidationError {
|
||||||
|
problem: format!(
|
||||||
|
"`extent[2]` is 1, but \
|
||||||
|
`drm_format_modifier_plane_layouts[{}].depth_pitch` is `Some`",
|
||||||
|
index
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
vuids: &["VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-depthPitch-02269"],
|
||||||
|
..Default::default()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
(ImageTiling::DrmFormatModifier, false) => {
|
||||||
if tiling == ImageTiling::DrmFormatModifier {
|
|
||||||
return Err(Box::new(ValidationError {
|
return Err(Box::new(ValidationError {
|
||||||
problem: "`tiling` is `ImageTiling::DrmFormatModifier`, but \
|
problem: "`tiling` is `ImageTiling::DrmFormatModifier`, but \
|
||||||
`drm_format_modifiers` is `None`"
|
`drm_format_modifiers` is empty"
|
||||||
.into(),
|
.into(),
|
||||||
vuids: &["VUID-VkImageCreateInfo-tiling-02261"],
|
vuids: &["VUID-VkImageCreateInfo-tiling-02261"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
(_, true) => {
|
||||||
if !drm_format_modifier_plane_layouts.is_empty() {
|
if tiling != ImageTiling::DrmFormatModifier {
|
||||||
return Err(Box::new(ValidationError {
|
return Err(Box::new(ValidationError {
|
||||||
problem: "`drm_format_modifiers` does not contain one element, but \
|
problem: "`drm_format_modifiers` is not empty, but \
|
||||||
`drm_format_modifier_plane_layouts` is not empty"
|
`tiling` is not `ImageTiling::DrmFormatModifier`"
|
||||||
.into(),
|
.into(),
|
||||||
..Default::default()
|
vuids: &["VUID-VkImageCreateInfo-pNext-02262"],
|
||||||
}));
|
..Default::default()
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
(_, false) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !external_memory_handle_types.is_empty() {
|
if !external_memory_handle_types.is_empty() {
|
||||||
|
Loading…
Reference in New Issue
Block a user