mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Import image from dma_buf following VK_EXT_external_memory_dma_buf (#2145)
* Import image from dma_buf Implements importing an image into Vulkan from a Linux dma_buf, according to the following Vulkan extensions: - https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_external_memory_dma_buf.html - https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_image_drm_format_modifier.html * Only compile dmabuf image importing on Linux Adds conditional compilation checks to functionality for importing vulkan images from a Linux dmabuf, as doing this only makes sense on Linux. * Add VUID checking for VkImageCreateInfo * Avoid Linux-only dependencies on other OSs * Add missing initializer to StorageImage * Add more VUID validation Check for VUID-vkGetPhysicalDeviceImageFormatProperties-tiling-02248, and VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02249 * Add some more VUIDs Or explanations of why they cannot yet be added * Small fix * Add suggested fixes Use lowercase for error, replace panic! with todo!, and make some comments show up in documentation.
This commit is contained in:
parent
836b9098ea
commit
b7ecee345d
@ -19,7 +19,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_enum},
|
macros::{impl_id_counter, vulkan_bitflags, vulkan_enum},
|
||||||
memory::MemoryProperties,
|
memory::{ExternalMemoryHandleType, MemoryProperties},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
ColorSpace, FullScreenExclusive, PresentMode, Surface, SurfaceApi, SurfaceCapabilities,
|
ColorSpace, FullScreenExclusive, PresentMode, Surface, SurfaceApi, SurfaceCapabilities,
|
||||||
SurfaceInfo, SurfaceTransforms,
|
SurfaceInfo, SurfaceTransforms,
|
||||||
@ -1023,6 +1023,9 @@ impl PhysicalDevice {
|
|||||||
image_view_type.validate_physical_device(self)?;
|
image_view_type.validate_physical_device(self)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02313
|
||||||
|
// Currently there is nothing in Vulkano for for adding a VkImageFormatListCreateInfo.
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,6 +1161,12 @@ impl PhysicalDevice {
|
|||||||
if !info2_vk.p_next.is_null() {
|
if !info2_vk.p_next.is_null() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
if let Some(ExternalMemoryHandleType::DmaBuf) = external_memory_handle_type
|
||||||
|
{
|
||||||
|
// VUID-vkGetPhysicalDeviceImageFormatProperties-tiling-02248
|
||||||
|
// VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02249
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
(fns.v1_0.get_physical_device_image_format_properties)(
|
(fns.v1_0.get_physical_device_image_format_properties)(
|
||||||
self.handle,
|
self.handle,
|
||||||
|
@ -58,6 +58,10 @@ pub use self::{
|
|||||||
usage::ImageUsage,
|
usage::ImageUsage,
|
||||||
view::{ImageViewAbstract, ImageViewType},
|
view::{ImageViewAbstract, ImageViewType},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub use self::storage::SubresourceData;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
format::Format,
|
format::Format,
|
||||||
macros::{vulkan_bitflags, vulkan_bitflags_enum, vulkan_enum},
|
macros::{vulkan_bitflags, vulkan_bitflags_enum, vulkan_enum},
|
||||||
@ -367,11 +371,10 @@ vulkan_enum! {
|
|||||||
// TODO: document
|
// TODO: document
|
||||||
Linear = LINEAR,
|
Linear = LINEAR,
|
||||||
|
|
||||||
/* TODO: enable
|
|
||||||
// TODO: document
|
// TODO: document
|
||||||
DrmFormatModifier = DRM_FORMAT_MODIFIER_EXT {
|
DrmFormatModifier = DRM_FORMAT_MODIFIER_EXT {
|
||||||
device_extensions: [ext_image_drm_format_modifier],
|
device_extensions: [ext_image_drm_format_modifier],
|
||||||
},*/
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The dimensions of an image.
|
/// The dimensions of an image.
|
||||||
|
@ -29,6 +29,17 @@ use crate::{
|
|||||||
DeviceSize,
|
DeviceSize,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use crate::{
|
||||||
|
image::ImageTiling,
|
||||||
|
memory::{allocator::MemoryAlloc, DeviceMemory, MemoryAllocateFlags, MemoryAllocateInfo},
|
||||||
|
};
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use ash::vk::{ImageDrmFormatModifierExplicitCreateInfoEXT, SubresourceLayout};
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use std::os::unix::prelude::{FromRawFd, IntoRawFd, RawFd};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
@ -223,6 +234,146 @@ impl StorageImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
/// Creates a new image from a set of Linux dma_buf file descriptors. The memory will be imported from the file desciptors, and will be bound to the image.
|
||||||
|
/// # Arguments
|
||||||
|
/// * `fds` - The list of file descriptors to import from. Single planar images should only use one, and multiplanar images can use multiple, for example, for each color.
|
||||||
|
/// * `offset` - The byte offset from the start of the image of the plane where the image subresource begins.
|
||||||
|
/// * `pitch` - Describes the number of bytes between each row of texels in an image.
|
||||||
|
pub fn new_from_dma_buf_fd(
|
||||||
|
allocator: &(impl MemoryAllocator + ?Sized),
|
||||||
|
device: Arc<Device>,
|
||||||
|
dimensions: ImageDimensions,
|
||||||
|
format: Format,
|
||||||
|
usage: ImageUsage,
|
||||||
|
flags: ImageCreateFlags,
|
||||||
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
|
mut subresource_data: Vec<SubresourceData>,
|
||||||
|
drm_format_modifier: u64,
|
||||||
|
) -> Result<Arc<StorageImage>, ImageError> {
|
||||||
|
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||||
|
|
||||||
|
// TODO: Support multiplanar image importing from Linux FD
|
||||||
|
if subresource_data.len() > 1 {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a vector of the layout of each image plane.
|
||||||
|
|
||||||
|
// All of the following are automatically true, since the values are explicitly set as such:
|
||||||
|
// VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-size-02267
|
||||||
|
// VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-arrayPitch-02268
|
||||||
|
// VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-depthPitch-02269
|
||||||
|
let layout: Vec<SubresourceLayout> = subresource_data
|
||||||
|
.iter_mut()
|
||||||
|
.map(
|
||||||
|
|SubresourceData {
|
||||||
|
fd: _,
|
||||||
|
offset,
|
||||||
|
row_pitch,
|
||||||
|
}| {
|
||||||
|
SubresourceLayout {
|
||||||
|
offset: *offset,
|
||||||
|
size: 0,
|
||||||
|
row_pitch: *row_pitch,
|
||||||
|
array_pitch: 0_u64,
|
||||||
|
depth_pitch: 0_u64,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let fds: Vec<RawFd> = subresource_data
|
||||||
|
.iter_mut()
|
||||||
|
.map(
|
||||||
|
|SubresourceData {
|
||||||
|
fd,
|
||||||
|
offset: _,
|
||||||
|
row_pitch: _,
|
||||||
|
}| { *fd },
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let drm_mod = ImageDrmFormatModifierExplicitCreateInfoEXT::builder()
|
||||||
|
.drm_format_modifier(drm_format_modifier)
|
||||||
|
.plane_layouts(layout.as_ref())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let external_memory_handle_types = ExternalMemoryHandleTypes::DMA_BUF;
|
||||||
|
|
||||||
|
let image = RawImage::new(
|
||||||
|
device.clone(),
|
||||||
|
ImageCreateInfo {
|
||||||
|
flags,
|
||||||
|
dimensions,
|
||||||
|
format: Some(format),
|
||||||
|
usage,
|
||||||
|
sharing: if queue_family_indices.len() >= 2 {
|
||||||
|
Sharing::Concurrent(queue_family_indices)
|
||||||
|
} else {
|
||||||
|
Sharing::Exclusive
|
||||||
|
},
|
||||||
|
external_memory_handle_types,
|
||||||
|
tiling: ImageTiling::DrmFormatModifier,
|
||||||
|
image_drm_format_modifier_create_info: Some(drm_mod),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let requirements = image.memory_requirements()[0];
|
||||||
|
let memory_type_index = allocator
|
||||||
|
.find_memory_type_index(requirements.memory_type_bits, MemoryUsage::GpuOnly.into())
|
||||||
|
.expect("failed to find a suitable memory type");
|
||||||
|
|
||||||
|
assert!(device.enabled_extensions().khr_external_memory_fd);
|
||||||
|
assert!(device.enabled_extensions().khr_external_memory);
|
||||||
|
assert!(device.enabled_extensions().ext_external_memory_dma_buf);
|
||||||
|
|
||||||
|
let memory = unsafe {
|
||||||
|
// TODO: For completeness, importing memory from muliple file descriptors should be added (In order to support importing multiplanar images). As of now, only single planar image importing will work.
|
||||||
|
if fds.len() != 1 {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try cloning underlying fd
|
||||||
|
let file = File::from_raw_fd(*fds.first().expect("file descriptor Vec is empty"));
|
||||||
|
let new_file = file.try_clone().expect("error cloning file descriptor");
|
||||||
|
|
||||||
|
// Turn the original file descriptor back into a raw fd to avoid ownership problems
|
||||||
|
file.into_raw_fd();
|
||||||
|
DeviceMemory::import(
|
||||||
|
device,
|
||||||
|
MemoryAllocateInfo {
|
||||||
|
allocation_size: requirements.layout.size(),
|
||||||
|
memory_type_index,
|
||||||
|
dedicated_allocation: Some(DedicatedAllocation::Image(&image)),
|
||||||
|
export_handle_types: ExternalMemoryHandleTypes::empty(),
|
||||||
|
flags: MemoryAllocateFlags::empty(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
crate::memory::MemoryImportInfo::Fd {
|
||||||
|
handle_type: crate::memory::ExternalMemoryHandleType::DmaBuf,
|
||||||
|
file: new_file,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap() // TODO: Handle
|
||||||
|
};
|
||||||
|
|
||||||
|
let mem_alloc = MemoryAlloc::new(memory).unwrap();
|
||||||
|
|
||||||
|
debug_assert!(mem_alloc.offset() % requirements.layout.alignment().as_nonzero() == 0);
|
||||||
|
debug_assert!(mem_alloc.size() == requirements.layout.size());
|
||||||
|
|
||||||
|
let inner = Arc::new(unsafe {
|
||||||
|
image
|
||||||
|
.bind_memory_unchecked([mem_alloc])
|
||||||
|
.map_err(|(err, _, _)| err)?
|
||||||
|
});
|
||||||
|
Ok(Arc::new(StorageImage {
|
||||||
|
inner,
|
||||||
|
layout_initialized: AtomicBool::new(false),
|
||||||
|
}))
|
||||||
|
}
|
||||||
/// Allows the creation of a simple 2D general purpose image view from `StorageImage`.
|
/// Allows the creation of a simple 2D general purpose image view from `StorageImage`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn general_purpose_image_view(
|
pub fn general_purpose_image_view(
|
||||||
@ -285,6 +436,20 @@ impl StorageImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
/// Struct that contains a Linux file descriptor for importing, when creating an image. Since a file descriptor is used for each
|
||||||
|
/// plane in the case of multiplanar images, each fd needs to have an offset and a row pitch in order to interpret the imported data.
|
||||||
|
pub struct SubresourceData {
|
||||||
|
/// The file descriptor handle of a layer of an image.
|
||||||
|
pub fd: RawFd,
|
||||||
|
|
||||||
|
/// The byte offset from the start of the plane where the image subresource begins.
|
||||||
|
pub offset: u64,
|
||||||
|
|
||||||
|
/// Describes the number of bytes between each row of texels in an image plane.
|
||||||
|
pub row_pitch: u64,
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl DeviceOwned for StorageImage {
|
unsafe impl DeviceOwned for StorageImage {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
|
@ -38,6 +38,7 @@ use crate::{
|
|||||||
sync::{future::AccessError, CurrentAccess, Sharing},
|
sync::{future::AccessError, CurrentAccess, Sharing},
|
||||||
DeviceSize, RequirementNotMet, RequiresOneOf, Version, VulkanError, VulkanObject,
|
DeviceSize, RequirementNotMet, RequiresOneOf, Version, VulkanError, VulkanObject,
|
||||||
};
|
};
|
||||||
|
use ash::vk::ImageDrmFormatModifierExplicitCreateInfoEXT;
|
||||||
use parking_lot::{Mutex, MutexGuard};
|
use parking_lot::{Mutex, MutexGuard};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::{
|
use std::{
|
||||||
@ -134,6 +135,7 @@ impl RawImage {
|
|||||||
initial_layout,
|
initial_layout,
|
||||||
external_memory_handle_types,
|
external_memory_handle_types,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
|
image_drm_format_modifier_create_info,
|
||||||
} = create_info;
|
} = create_info;
|
||||||
|
|
||||||
let physical_device = device.physical_device();
|
let physical_device = device.physical_device();
|
||||||
@ -206,6 +208,14 @@ impl RawImage {
|
|||||||
|| flags.intersects(ImageCreateFlags::MUTABLE_FORMAT)
|
|| flags.intersects(ImageCreateFlags::MUTABLE_FORMAT)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// VUID-VkImageCreateInfo-tiling-02261
|
||||||
|
// VUID-VkImageCreateInfo-pNext-02262
|
||||||
|
if (tiling == ImageTiling::DrmFormatModifier)
|
||||||
|
!= image_drm_format_modifier_create_info.is_some()
|
||||||
|
{
|
||||||
|
return Err(ImageError::DrmFormatModifierRequiresCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
// Get format features
|
// Get format features
|
||||||
let format_features = {
|
let format_features = {
|
||||||
// Use unchecked, because all validation has been done above.
|
// Use unchecked, because all validation has been done above.
|
||||||
@ -213,9 +223,13 @@ impl RawImage {
|
|||||||
match tiling {
|
match tiling {
|
||||||
ImageTiling::Linear => format_properties.linear_tiling_features,
|
ImageTiling::Linear => format_properties.linear_tiling_features,
|
||||||
ImageTiling::Optimal => format_properties.optimal_tiling_features,
|
ImageTiling::Optimal => format_properties.optimal_tiling_features,
|
||||||
|
ImageTiling::DrmFormatModifier => format_properties.linear_tiling_features, // TODO: Improve
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: VUID-VkImageCreateInfo-tiling-02353
|
||||||
|
// Vulkano currently has no high-level way to add or check for VkImageFormatListCreateInfo.
|
||||||
|
|
||||||
// Format isn't supported at all?
|
// Format isn't supported at all?
|
||||||
if format_features.is_empty() {
|
if format_features.is_empty() {
|
||||||
return Err(ImageError::FormatNotSupported);
|
return Err(ImageError::FormatNotSupported);
|
||||||
@ -871,6 +885,7 @@ impl RawImage {
|
|||||||
initial_layout,
|
initial_layout,
|
||||||
external_memory_handle_types,
|
external_memory_handle_types,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
|
mut image_drm_format_modifier_create_info,
|
||||||
} = &create_info;
|
} = &create_info;
|
||||||
|
|
||||||
let aspects = format.map_or_else(Default::default, |format| format.aspects());
|
let aspects = format.map_or_else(Default::default, |format| format.aspects());
|
||||||
@ -953,6 +968,13 @@ impl RawImage {
|
|||||||
info_vk.p_next = next as *const _ as *const _;
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if external_memory_handle_types.intersects(ExternalMemoryHandleTypes::DMA_BUF) {
|
||||||
|
let next = image_drm_format_modifier_create_info.as_mut().unwrap();
|
||||||
|
|
||||||
|
next.p_next = info_vk.p_next;
|
||||||
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
|
}
|
||||||
|
|
||||||
let handle = {
|
let handle = {
|
||||||
let fns = device.fns();
|
let fns = device.fns();
|
||||||
let mut output = MaybeUninit::uninit();
|
let mut output = MaybeUninit::uninit();
|
||||||
@ -1000,6 +1022,7 @@ impl RawImage {
|
|||||||
initial_layout,
|
initial_layout,
|
||||||
external_memory_handle_types,
|
external_memory_handle_types,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
|
image_drm_format_modifier_create_info: _,
|
||||||
} = create_info;
|
} = create_info;
|
||||||
|
|
||||||
let aspects = format.map_or_else(Default::default, |format| format.aspects());
|
let aspects = format.map_or_else(Default::default, |format| format.aspects());
|
||||||
@ -1020,6 +1043,7 @@ impl RawImage {
|
|||||||
match tiling {
|
match tiling {
|
||||||
ImageTiling::Linear => format_properties.linear_tiling_features,
|
ImageTiling::Linear => format_properties.linear_tiling_features,
|
||||||
ImageTiling::Optimal => format_properties.optimal_tiling_features,
|
ImageTiling::Optimal => format_properties.optimal_tiling_features,
|
||||||
|
ImageTiling::DrmFormatModifier => format_properties.linear_tiling_features, // TODO: improve
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1755,7 +1779,10 @@ impl RawImage {
|
|||||||
// Ensured by use of enum `ImageAspect`.
|
// Ensured by use of enum `ImageAspect`.
|
||||||
|
|
||||||
// VUID-vkGetImageSubresourceLayout-image-02270
|
// VUID-vkGetImageSubresourceLayout-image-02270
|
||||||
if !matches!(self.tiling, ImageTiling::Linear) {
|
if !matches!(
|
||||||
|
self.tiling,
|
||||||
|
ImageTiling::DrmFormatModifier | ImageTiling::Linear
|
||||||
|
) {
|
||||||
return Err(ImageError::OptimalTilingNotSupported);
|
return Err(ImageError::OptimalTilingNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1792,6 +1819,11 @@ impl RawImage {
|
|||||||
allowed_aspects -= ImageAspects::COLOR;
|
allowed_aspects -= ImageAspects::COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: VUID-vkGetImageSubresourceLayout-tiling-02271
|
||||||
|
//if self.tiling == ImageTiling::DrmFormatModifier {
|
||||||
|
// Only one-plane image importing is possible for now.
|
||||||
|
//}
|
||||||
|
|
||||||
// VUID-vkGetImageSubresourceLayout-format-04461
|
// VUID-vkGetImageSubresourceLayout-format-04461
|
||||||
// VUID-vkGetImageSubresourceLayout-format-04462
|
// VUID-vkGetImageSubresourceLayout-format-04462
|
||||||
// VUID-vkGetImageSubresourceLayout-format-04463
|
// VUID-vkGetImageSubresourceLayout-format-04463
|
||||||
@ -1962,6 +1994,9 @@ pub struct ImageCreateInfo {
|
|||||||
/// The default value is [`ExternalMemoryHandleTypes::empty()`].
|
/// The default value is [`ExternalMemoryHandleTypes::empty()`].
|
||||||
pub external_memory_handle_types: ExternalMemoryHandleTypes,
|
pub external_memory_handle_types: ExternalMemoryHandleTypes,
|
||||||
|
|
||||||
|
/// Specify that an image be created with the provided DRM format modifier and explicit memory layout
|
||||||
|
pub image_drm_format_modifier_create_info: Option<ImageDrmFormatModifierExplicitCreateInfoEXT>,
|
||||||
|
|
||||||
pub _ne: crate::NonExhaustive,
|
pub _ne: crate::NonExhaustive,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1984,6 +2019,7 @@ impl Default for ImageCreateInfo {
|
|||||||
sharing: Sharing::Exclusive,
|
sharing: Sharing::Exclusive,
|
||||||
initial_layout: ImageLayout::Undefined,
|
initial_layout: ImageLayout::Undefined,
|
||||||
external_memory_handle_types: ExternalMemoryHandleTypes::empty(),
|
external_memory_handle_types: ExternalMemoryHandleTypes::empty(),
|
||||||
|
image_drm_format_modifier_create_info: None,
|
||||||
_ne: crate::NonExhaustive(()),
|
_ne: crate::NonExhaustive(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2960,6 +2996,9 @@ pub enum ImageError {
|
|||||||
YcbcrFormatNot2d,
|
YcbcrFormatNot2d,
|
||||||
|
|
||||||
DirectImageViewCreationFailed(ImageViewCreationError),
|
DirectImageViewCreationFailed(ImageViewCreationError),
|
||||||
|
|
||||||
|
/// If and only if tiling is `DRMFormatModifier`, then `image_drm_format_modifier_create_info` must not be `None`.
|
||||||
|
DrmFormatModifierRequiresCreateInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ImageError {
|
impl Error for ImageError {
|
||||||
@ -3219,6 +3258,7 @@ impl Display for ImageError {
|
|||||||
write!(f, "a YCbCr format was given, but the image type was not 2D")
|
write!(f, "a YCbCr format was given, but the image type was not 2D")
|
||||||
}
|
}
|
||||||
Self::DirectImageViewCreationFailed(e) => write!(f, "Image view creation failed {}", e),
|
Self::DirectImageViewCreationFailed(e) => write!(f, "Image view creation failed {}", e),
|
||||||
|
Self::DrmFormatModifierRequiresCreateInfo => write!(f, "If and only if tiling is `DRMFormatModifier`, then `image_drm_format_modifier_create_info` must be `Some`"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,6 +726,7 @@ where
|
|||||||
match image.tiling() {
|
match image.tiling() {
|
||||||
ImageTiling::Optimal => format_properties.optimal_tiling_features,
|
ImageTiling::Optimal => format_properties.optimal_tiling_features,
|
||||||
ImageTiling::Linear => format_properties.linear_tiling_features,
|
ImageTiling::Linear => format_properties.linear_tiling_features,
|
||||||
|
ImageTiling::DrmFormatModifier => format_properties.linear_tiling_features,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
image.format_features()
|
image.format_features()
|
||||||
|
@ -784,6 +784,7 @@ impl From<ImageTiling> for AllocationType {
|
|||||||
match tiling {
|
match tiling {
|
||||||
ImageTiling::Optimal => AllocationType::NonLinear,
|
ImageTiling::Optimal => AllocationType::NonLinear,
|
||||||
ImageTiling::Linear => AllocationType::Linear,
|
ImageTiling::Linear => AllocationType::Linear,
|
||||||
|
ImageTiling::DrmFormatModifier => AllocationType::Linear, // TODO: improve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user