From 82d37247d89dd5e42e13b10c3b5a184ba13b5063 Mon Sep 17 00:00:00 2001 From: janis Date: Thu, 2 Apr 2026 23:10:01 +0200 Subject: [PATCH] image view type validation --- crates/renderer/src/egui.rs | 24 +-- crates/renderer/src/images.rs | 260 +++++++++------------------ crates/renderer/src/lib.rs | 2 + crates/renderer/src/render_graph.rs | 2 +- crates/renderer/src/rendering/mod.rs | 7 +- 5 files changed, 92 insertions(+), 203 deletions(-) diff --git a/crates/renderer/src/egui.rs b/crates/renderer/src/egui.rs index 187b72d..8bb3653 100644 --- a/crates/renderer/src/egui.rs +++ b/crates/renderer/src/egui.rs @@ -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); diff --git a/crates/renderer/src/images.rs b/crates/renderer/src/images.rs index 7575aa0..6e6291e 100644 --- a/crates/renderer/src/images.rs +++ b/crates/renderer/src/images.rs @@ -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>(self, range: R) -> Self { + Self { + mip_range: range.into(), + ..self + } + } + + pub fn with_layer_range>(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>) -> 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 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 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, diff --git a/crates/renderer/src/lib.rs b/crates/renderer/src/lib.rs index 53018d1..91f905f 100644 --- a/crates/renderer/src/lib.rs +++ b/crates/renderer/src/lib.rs @@ -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 = core::result::Result; diff --git a/crates/renderer/src/render_graph.rs b/crates/renderer/src/render_graph.rs index fa6f82f..a56f0d0 100644 --- a/crates/renderer/src/render_graph.rs +++ b/crates/renderer/src/render_graph.rs @@ -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}, }; diff --git a/crates/renderer/src/rendering/mod.rs b/crates/renderer/src/rendering/mod.rs index 2c32b81..7743b84 100644 --- a/crates/renderer/src/rendering/mod.rs +++ b/crates/renderer/src/rendering/mod.rs @@ -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);