mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 14:56:42 +00:00
Better error message when source is too small for ImmutableImage
(#2022)
This commit is contained in:
parent
f99c67929f
commit
de920e4a3c
@ -16,7 +16,7 @@ use crate::{
|
||||
buffer::{BufferAccess, BufferContents, BufferUsage, CpuAccessibleBuffer},
|
||||
command_buffer::{
|
||||
allocator::CommandBufferAllocator, AutoCommandBufferBuilder, BlitImageInfo,
|
||||
CommandBufferBeginError, CommandBufferExecFuture, CommandBufferUsage,
|
||||
BufferImageCopy, CommandBufferBeginError, CommandBufferExecFuture, CommandBufferUsage,
|
||||
CopyBufferToImageInfo, ImageBlit, PrimaryCommandBuffer,
|
||||
},
|
||||
device::{Device, DeviceOwned, Queue},
|
||||
@ -31,9 +31,9 @@ use crate::{
|
||||
},
|
||||
sampler::Filter,
|
||||
sync::{NowFuture, Sharing},
|
||||
OomError,
|
||||
DeviceSize, OomError,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{Display, Error as FmtError, Formatter},
|
||||
@ -218,6 +218,23 @@ impl ImmutableImage {
|
||||
command_buffer_allocator: &impl CommandBufferAllocator,
|
||||
queue: Arc<Queue>,
|
||||
) -> Result<(Arc<Self>, CommandBufferExecFuture<NowFuture>), ImmutableImageCreationError> {
|
||||
let region = BufferImageCopy {
|
||||
image_subresource: ImageSubresourceLayers::from_parameters(
|
||||
format,
|
||||
dimensions.array_layers(),
|
||||
),
|
||||
image_extent: dimensions.width_height_depth(),
|
||||
..Default::default()
|
||||
};
|
||||
let required_size = region.buffer_copy_size(format);
|
||||
|
||||
if source.size() < required_size {
|
||||
return Err(ImmutableImageCreationError::SourceTooSmall {
|
||||
source_size: source.size(),
|
||||
required_size,
|
||||
});
|
||||
}
|
||||
|
||||
let need_to_generate_mipmaps = has_mipmaps(mip_levels);
|
||||
let usage = ImageUsage {
|
||||
transfer_dst: true,
|
||||
@ -248,7 +265,10 @@ impl ImmutableImage {
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
)?;
|
||||
cbb.copy_buffer_to_image(CopyBufferToImageInfo::buffer_image(source, initializer))
|
||||
cbb.copy_buffer_to_image(CopyBufferToImageInfo {
|
||||
regions: smallvec![region],
|
||||
..CopyBufferToImageInfo::buffer_image(source, initializer)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
if need_to_generate_mipmaps {
|
||||
@ -394,11 +414,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Error that can happen when creating an `ImmutableImage`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ImmutableImageCreationError {
|
||||
ImageCreationError(ImageCreationError),
|
||||
DeviceMemoryAllocationError(DeviceMemoryError),
|
||||
CommandBufferBeginError(CommandBufferBeginError),
|
||||
|
||||
/// The size of the provided source data is less than the required size for an image with the
|
||||
/// given format and dimensions.
|
||||
SourceTooSmall {
|
||||
source_size: DeviceSize,
|
||||
required_size: DeviceSize,
|
||||
},
|
||||
}
|
||||
|
||||
impl Error for ImmutableImageCreationError {
|
||||
@ -407,6 +435,7 @@ impl Error for ImmutableImageCreationError {
|
||||
Self::ImageCreationError(err) => Some(err),
|
||||
Self::DeviceMemoryAllocationError(err) => Some(err),
|
||||
Self::CommandBufferBeginError(err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -417,6 +446,15 @@ impl Display for ImmutableImageCreationError {
|
||||
Self::ImageCreationError(err) => err.fmt(f),
|
||||
Self::DeviceMemoryAllocationError(err) => err.fmt(f),
|
||||
Self::CommandBufferBeginError(err) => err.fmt(f),
|
||||
|
||||
Self::SourceTooSmall {
|
||||
source_size,
|
||||
required_size,
|
||||
} => write!(
|
||||
f,
|
||||
"the size of the provided source data ({} bytes) is less than the required size for an image of the given format and dimensions ({} bytes)",
|
||||
source_size, required_size,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,6 +518,31 @@ pub struct ImageSubresourceLayers {
|
||||
pub array_layers: Range<u32>,
|
||||
}
|
||||
|
||||
impl ImageSubresourceLayers {
|
||||
/// Returns an `ImageSubresourceLayers` from the given image parameters, covering the first
|
||||
/// mip level of the image. All aspects of the image are selected, or `plane0` if the image
|
||||
/// is multi-planar.
|
||||
#[inline]
|
||||
pub fn from_parameters(format: Format, array_layers: u32) -> Self {
|
||||
Self {
|
||||
aspects: {
|
||||
let aspects = format.aspects();
|
||||
|
||||
if aspects.plane0 {
|
||||
ImageAspects {
|
||||
plane0: true,
|
||||
..ImageAspects::empty()
|
||||
}
|
||||
} else {
|
||||
aspects
|
||||
}
|
||||
},
|
||||
mip_level: 0,
|
||||
array_layers: 0..array_layers,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ImageSubresourceLayers> for ash::vk::ImageSubresourceLayers {
|
||||
#[inline]
|
||||
fn from(val: ImageSubresourceLayers) -> Self {
|
||||
@ -550,6 +575,24 @@ pub struct ImageSubresourceRange {
|
||||
pub array_layers: Range<u32>,
|
||||
}
|
||||
|
||||
impl ImageSubresourceRange {
|
||||
/// Returns an `ImageSubresourceRange` from the given image parameters, covering the whole
|
||||
/// image. If the image is multi-planar, only the `color` aspect is selected.
|
||||
#[inline]
|
||||
pub fn from_parameters(format: Format, mip_levels: u32, array_layers: u32) -> Self {
|
||||
Self {
|
||||
aspects: ImageAspects {
|
||||
plane0: false,
|
||||
plane1: false,
|
||||
plane2: false,
|
||||
..format.aspects()
|
||||
},
|
||||
mip_levels: 0..mip_levels,
|
||||
array_layers: 0..array_layers,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ImageSubresourceRange> for ash::vk::ImageSubresourceRange {
|
||||
#[inline]
|
||||
fn from(val: ImageSubresourceRange) -> Self {
|
||||
|
@ -107,22 +107,7 @@ pub unsafe trait ImageAccess: DeviceOwned + Send + Sync {
|
||||
/// of the image are selected, or `plane0` if the image is multi-planar.
|
||||
#[inline]
|
||||
fn subresource_layers(&self) -> ImageSubresourceLayers {
|
||||
ImageSubresourceLayers {
|
||||
aspects: {
|
||||
let aspects = self.format().aspects();
|
||||
|
||||
if aspects.plane0 {
|
||||
ImageAspects {
|
||||
plane0: true,
|
||||
..ImageAspects::empty()
|
||||
}
|
||||
} else {
|
||||
aspects
|
||||
}
|
||||
},
|
||||
mip_level: 0,
|
||||
array_layers: 0..self.dimensions().array_layers(),
|
||||
}
|
||||
ImageSubresourceLayers::from_parameters(self.format(), self.dimensions().array_layers())
|
||||
}
|
||||
|
||||
/// Returns an `ImageSubresourceRange` covering the whole image. If the image is multi-planar,
|
||||
|
Loading…
Reference in New Issue
Block a user