image view type validation

This commit is contained in:
janis 2026-04-02 23:10:01 +02:00
parent 2f05c97bda
commit 82d37247d8
5 changed files with 92 additions and 203 deletions

View file

@ -525,14 +525,11 @@ pub fn egui_pass(
vk::DescriptorImageInfo {
sampler: samplers.get_sampler(entry.as_sampler_desc()).unwrap(),
image_view: texture
.create_view(ImageViewDesc {
kind: vk::ImageViewType::TYPE_2D,
format: texture.format(),
aspect: vk::ImageAspectFlags::COLOR,
mip_range: (0..1).into(),
layer_range: (0..1).into(),
..Default::default()
})
.create_view(
ImageViewDesc::color_2d()
.with_mip_range(0..1)
.with_layer_range(0..1),
)
.unwrap()
.raw(),
image_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
@ -669,16 +666,7 @@ pub fn egui_pass(
let color_attachment = &vk::RenderingAttachmentInfo::default()
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.image_view(
target
.create_view(ImageViewDesc {
kind: vk::ImageViewType::TYPE_2D,
format: target.format(),
aspect: vk::ImageAspectFlags::COLOR,
..Default::default()
})?
.raw(),
)
.image_view(target.create_view(ImageViewDesc::color_2d())?.raw())
.load_op(vk::AttachmentLoadOp::LOAD)
.store_op(vk::AttachmentStoreOp::STORE);

View file

@ -411,13 +411,26 @@ impl Image {
desc.mip_range,
self.desc.mip_levels
);
return Err(crate::Error::Unspecified);
return Err(crate::Error::Todo(
"image view mip range exceeds image mip levels",
));
}
if desc.format == vk::Format::UNDEFINED {
desc.format = self.desc.format;
}
if !validate_image_view_format(&self.desc, desc.format) {
tracing::error!(
"image view format {:?} is not compatible with image format {:?}",
desc.format,
self.desc.format
);
return Err(crate::Error::Todo(
"image view format is not compatible with image format",
));
}
let create_info = vk::ImageViewCreateInfo::default()
.flags(desc.flags)
.image(self.image())
@ -444,7 +457,16 @@ impl Image {
}
}
fn validate_image_view_format(image: &ImageDesc, view_format: vk::Format) -> bool {}
fn validate_image_view_format(image: &ImageDesc, view_format: vk::Format) -> bool {
let mutable = image.flags.contains(vk::ImageCreateFlags::MUTABLE_FORMAT);
if mutable {
image.format == view_format
|| FormatClass::from(image.format) == FormatClass::from(view_format)
} else {
image.format == view_format
}
}
fn view_kind_compatible(image_kind: vk::ImageType, view_kind: vk::ImageViewType) -> bool {
use vk::ImageType as IT;
@ -482,6 +504,31 @@ impl ImageViewDesc {
Self { format, ..self }
}
pub fn with_mip_range<R: core::ops::RangeBounds<u32>>(self, range: R) -> Self {
Self {
mip_range: range.into(),
..self
}
}
pub fn with_layer_range<R: core::ops::RangeBounds<u32>>(self, range: R) -> Self {
Self {
layer_range: range.into(),
..self
}
}
pub fn with_aspect(self, aspect: vk::ImageAspectFlags) -> Self {
Self { aspect, ..self }
}
pub fn with_name(self, name: impl Into<Cow<'static, str>>) -> Self {
Self {
name: Some(name.into()),
..self
}
}
pub(crate) fn hash_eq_copy(&self) -> Self {
let &Self {
flags,
@ -625,150 +672,7 @@ pub const SUBRESOURCERANGE_COLOR_ALL: vk::ImageSubresourceRange = vk::ImageSubre
layer_count: vk::REMAINING_ARRAY_LAYERS,
};
// pub(crate) enum FormatClass {
// Bit8,
// Bit8Alpha,
// Bit16,
// Bit24,
// Bit32,
// Bit48,
// Bit64,
// Bit96,
// Bit128,
// Bit192,
// Bit256,
// D16,
// D24,
// D32,
// S8,
// D16S8,
// D24S8,
// D32S8,
// Bc1Rrb,
// Bc1Rgba,
// Bc2,
// Bc3,
// Bc4,
// Bc5,
// Bc6H,
// BC7,
// Etc2Rgb,
// Etc2Rgba,
// Etc2EacRgba,
// EacR,
// EacRg,
// // Astc formats:
// Astc4x4,
// Astc5x4,
// Astc5x5,
// Astc6x5,
// Astc6x6,
// Astc8x5,
// Astc8x6,
// Astc8x8,
// Astc10x5,
// Astc10x6,
// Astc10x8,
// Astc10x10,
// Astc12x10,
// Astc12x12,
// // Astc 3d formats:
// Astc3x3x3,
// Astc4x3x3,
// Astc4x4x3,
// Astc4x4x4,
// Astc5x4x4,
// Astc5x5x4,
// Astc5x5x5,
// Astc6x5x5,
// Astc6x6x5,
// Astc6x6x6,
// // padded color formats:
// Bit32Gbgr8,
// Bit32Gbrg8,
// Bit64Rgba10,
// Bit64Gbgr10,
// Bit64Bgrg10,
// Bit64Rgba12,
// Bit64Gbgr12,
// Bit64Bgrg12,
// Bit64Rgba14,
// Bit64Rgba16,
// Bit64Gbgr16,
// Bit64Bgrg16,
// // planar formats:
// Bit8Biplane420,
// Bit8Biplane422,
// Bit8Biplane444,
// Bit8Triplane420,
// Bit8Triplane422,
// Bit8Triplane444,
// Bit10Biplane420,
// Bit10Biplane422,
// Bit10Biplane444,
// Bit10Triplane420,
// Bit10Triplane422,
// Bit10Triplane444,
// Bit12Biplane420,
// Bit12Biplane422,
// Bit12Biplane444,
// Bit12Triplane420,
// Bit12Triplane422,
// Bit12Triplane444,
// Bit16Biplane420,
// Bit16Biplane422,
// Bit16Biplane444,
// Bit16Triplane420,
// Bit16Triplane422,
// Bit16Triplane444,
// // PVRTC formats:
// Pvrtc1Bpp2,
// Pvrtc1Bpp4,
// Pvrtc2Bpp2,
// Pvrtc2Bpp4,
// }
// pub(crate) struct FormatInfo {
// class: FormatClass,
// texel_size: u32,
// block_extent: (u32, u32, u32),
// texels_per_block: u32,
// }
// impl From<vk::Format> for FormatClass {
// fn from(value: vk::Format) -> Self {
// use vk::Format as F;
// #[rustfmt::skip]
// match value {
// F::R4G4_UNORM_PACK8
// | F::R8_SNORM
// | F::R8_USCALED
// | F::R8_SSCALED
// | F::R8_UINT
// | F::R8_SINT
// | F::R8_SRGB
// => Self::Bit8,
// F::A1R5G5B5_UNORM_PACK16
// | F::R4G4B4A4_UNORM_PACK16
// | F::B4G4R4A4_UNORM_PACK16
// | F::R5G6B5_UNORM_PACK16
// | F::R10X6_UNORM_PACK16
// |F::R12X4_UNORM_PACK16
// | F::R8G8_UNORM => Self::Bit16,
// _ => unimplemented!("format class for format {:?}", value),
// }
// }
// }
// copilot generated from spec:
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FormatClass {
Bits8,
@ -1120,75 +1024,75 @@ impl From<vk::Format> for FormatClass {
F::G8B8G8R8_422_UNORM => FormatClass::YuvG8B8G8R8_422,
F::B8G8R8G8_422_UNORM => FormatClass::YuvB8G8R8G8_422,
F::G8_B8_R8_3PLANE_420_UNORM => FormatClass::YuvG8_B8_R8_3Plane_420,
F::G8_B8R8_2PLANE_420_UNORM => FormatClass::YuvG8_B8R8_2Plane_420,
F::G8_B8_R8_3PLANE_422_UNORM => FormatClass::YuvG8_B8_R8_3Plane_422,
F::G8_B8R8_2PLANE_422_UNORM => FormatClass::YuvG8_B8R8_2Plane_422,
F::G8_B8_R8_3PLANE_444_UNORM => FormatClass::YuvG8_B8_R8_3Plane_444,
F::G8_B8_R8_3PLANE_420_UNORM => FormatClass::YuvG8B8R8Triplane420,
F::G8_B8R8_2PLANE_420_UNORM => FormatClass::YuvG8B8R8Biplane420,
F::G8_B8_R8_3PLANE_422_UNORM => FormatClass::YuvG8B8R8Triplane422,
F::G8_B8R8_2PLANE_422_UNORM => FormatClass::YuvG8B8R8Biplane422,
F::G8_B8_R8_3PLANE_444_UNORM => FormatClass::YuvG8B8R8Triplane444,
F::G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 => {
FormatClass::YuvG10X6_B10X6_R10X6_3Plane_420
FormatClass::YuvG10X6B10X6R10X6Triplane420
}
F::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 => {
FormatClass::YuvG10X6_B10X6R10X6_2Plane_420
FormatClass::YuvG10X6B10X6R10X6Biplane420
}
F::G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 => {
FormatClass::YuvG10X6_B10X6_R10X6_3Plane_422
FormatClass::YuvG10X6B10X6R10X6Triplane422
}
F::G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 => {
FormatClass::YuvG10X6_B10X6R10X6_2Plane_422
FormatClass::YuvG10X6B10X6R10X6Biplane422
}
F::G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 => {
FormatClass::YuvG10X6_B10X6_R10X6_3Plane_444
FormatClass::YuvG10X6B10X6R10X6Triplane444
}
F::G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 => {
FormatClass::YuvG12X4_B12X4_R12X4_3Plane_420
FormatClass::YuvG12X4B12X4R12X4Triplane420
}
F::G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 => {
FormatClass::YuvG12X4_B12X4R12X4_2Plane_420
FormatClass::YuvG12X4B12X4R12X4Biplane420
}
F::G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 => {
FormatClass::YuvG12X4_B12X4_R12X4_3Plane_422
FormatClass::YuvG12X4B12X4R12X4Triplane422
}
F::G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 => {
FormatClass::YuvG12X4_B12X4R12X4_2Plane_422
FormatClass::YuvG12X4B12X4R12X4Biplane422
}
F::G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 => {
FormatClass::YuvG12X4_B12X4_R12X4_3Plane_444
FormatClass::YuvG12X4B12X4R12X4Triplane444
}
F::G16_B16_R16_3PLANE_420_UNORM => FormatClass::YuvG16_B16_R16_3Plane_420,
F::G16_B16R16_2PLANE_420_UNORM => FormatClass::YuvG16_B16R16_2Plane_420,
F::G16_B16_R16_3PLANE_422_UNORM => FormatClass::YuvG16_B16_R16_3Plane_422,
F::G16_B16R16_2PLANE_422_UNORM => FormatClass::YuvG16_B16R16_2Plane_422,
F::G16_B16_R16_3PLANE_444_UNORM => FormatClass::YuvG16_B16_R16_3Plane_444,
F::G16_B16_R16_3PLANE_420_UNORM => FormatClass::YuvG16B16R16Triplane420,
F::G16_B16R16_2PLANE_420_UNORM => FormatClass::YuvG16B16R16Biplane420,
F::G16_B16_R16_3PLANE_422_UNORM => FormatClass::YuvG16B16R16Triplane422,
F::G16_B16R16_2PLANE_422_UNORM => FormatClass::YuvG16B16R16Biplane422,
F::G16_B16_R16_3PLANE_444_UNORM => FormatClass::YuvG16B16R16Triplane444,
// 2-plane 444 (additional section)
F::G8_B8R8_2PLANE_444_UNORM => FormatClass::YuvG8_B8R8_2Plane_444,
F::G8_B8R8_2PLANE_444_UNORM => FormatClass::YuvG8B8R8Biplane444,
F::G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 => {
FormatClass::YuvG10X6_B10X6R10X6_2Plane_444
FormatClass::YuvG10X6B10X6R10X6Biplane444
}
F::G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 => {
FormatClass::YuvG12X4_B12X4R12X4_2Plane_444
FormatClass::YuvG12X4B12X4R12X4Biplane444
}
F::G16_B16R16_2PLANE_444_UNORM => FormatClass::YuvG16_B16R16_2Plane_444,
F::G16_B16R16_2PLANE_444_UNORM => FormatClass::YuvG16B16R16Biplane444,
// 64-bit special grouped headings from the markdown
F::R10X6G10X6B10X6A10X6_UNORM_4PACK16 /* | F::R10X6G10X6B10X6A10X6_UINT_4PACK16_ARM */
=> {
FormatClass::Bits64_R10G10B10A10
FormatClass::Bits64R10G10B10A10
}
F::G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 => FormatClass::Bits64_G10B10G10R10_422,
F::B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 => FormatClass::Bits64_B10G10R10G10_422,
F::G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 => FormatClass::Bits64G10B10G10R10_422,
F::B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 => FormatClass::Bits64B10G10R10G10_422,
F::R12X4G12X4B12X4A12X4_UNORM_4PACK16 /*| F::R12X4G12X4B12X4A12X4_UINT_4PACK16_ARM */
=> {
FormatClass::Bits64_R12G12B12A12
FormatClass::Bits64R12G12B12A12
}
F::G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 => FormatClass::Bits64_G12B12G12R12_422,
F::B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 => FormatClass::Bits64_B12G12R12G12_422,
F::G16B16G16R16_422_UNORM => FormatClass::Bits64_G16B16G16R16_422,
F::B16G16R16G16_422_UNORM => FormatClass::Bits64_B16G16R16G16_422,
F::G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 => FormatClass::Bits64G12B12G12R12_422,
F::B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 => FormatClass::Bits64B12G12R12G12_422,
F::G16B16G16R16_422_UNORM => FormatClass::Bits64G16B16G16R16_422,
F::B16G16R16G16_422_UNORM => FormatClass::Bits64B16G16R16G16_422,
// F::R14X2G14X2B14X2A14X2_UINT_4PACK16_ARM
// | F::R14X2G14X2B14X2A14X2_UNORM_4PACK16_ARM => FormatClass::Bits64_R14G14B14A14,

View file

@ -118,6 +118,8 @@ pub enum Error {
},
#[error("Unspecified Error")]
Unspecified,
#[error("BEEP BOOP create an error variant for {0} BEEP BOOP")]
Todo(&'static str),
}
pub type Result<T> = core::result::Result<T, Error>;

View file

@ -10,7 +10,7 @@ use crate::{
buffers::{Buffer, BufferDesc},
commands::{self, traits::CommandBufferExt},
def_monotonic_id,
device::{self, DeviceOwned},
device::{self},
images::{self, Image, ImageDesc},
util::{self, Rgba, WithLifetime},
};

View file

@ -334,12 +334,7 @@ impl Wireframe {
let color_attachment = &vk::RenderingAttachmentInfo::default()
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.image_view(target.get_view(ImageViewDesc {
kind: vk::ImageViewType::TYPE_2D,
format: target.format(),
aspect: vk::ImageAspectFlags::COLOR,
..Default::default()
})?)
.image_view(target.create_view(ImageViewDesc::color_2d())?.raw())
.load_op(vk::AttachmentLoadOp::LOAD)
.store_op(vk::AttachmentStoreOp::STORE);