feat(renderer): create image views for swapchain images

This commit is contained in:
Serkyo 2026-05-09 17:29:47 +02:00
parent 636c44b29f
commit 65b43651bb

View file

@ -39,6 +39,8 @@ pub struct Renderer {
swapchain_format: vk::Format, swapchain_format: vk::Format,
/// The resolution of the swapchain images. /// The resolution of the swapchain images.
swapchain_extent: vk::Extent2D, swapchain_extent: vk::Extent2D,
/// The views into the swapchain images.
swapchain_image_views: Vec<vk::ImageView>,
} }
impl Renderer { impl Renderer {
@ -123,6 +125,9 @@ impl Renderer {
let (swapchain_loader, swapchain, swapchain_images, swapchain_format, swapchain_extent) = let (swapchain_loader, swapchain, swapchain_images, swapchain_format, swapchain_extent) =
Self::create_swapchain(&instance, physical_device, &device, &surface_loader, surface, width, height)?; Self::create_swapchain(&instance, physical_device, &device, &surface_loader, surface, width, height)?;
// Create image views for the swapchain images
let image_views = Self::create_image_views(&device, &swapchain_images, swapchain_format)?;
Ok(Self { Ok(Self {
_entry: entry, _entry: entry,
instance, instance,
@ -139,6 +144,7 @@ impl Renderer {
swapchain_images, swapchain_images,
swapchain_format, swapchain_format,
swapchain_extent, swapchain_extent,
swapchain_image_views: image_views,
}) })
} }
@ -307,27 +313,68 @@ impl Renderer {
Ok((swapchain_loader, swapchain, images, format.format, extent )) Ok((swapchain_loader, swapchain, images, format.format, extent ))
} }
/// Creates image views for the swapchain images.
///
/// An image view describes how to access an image (e.g. as a 2D texture).
fn create_image_views(
device: &Device,
images: &[vk::Image],
format: vk::Format,
) -> Result<Vec<vk::ImageView>, RendererError> {
let mut views = Vec::with_capacity(images.len());
for &image in images {
let create_info = vk::ImageViewCreateInfo::default()
.image(image)
.view_type(vk::ImageViewType::TYPE_2D)
.format(format)
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::IDENTITY,
g: vk::ComponentSwizzle::IDENTITY,
b: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY,
})
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
});
let view = unsafe { device.create_image_view(&create_info, None)? };
views.push(view);
}
Ok(views)
}
} }
/// Ensures all Vulkan resources are destroyed in the correct order. /// Ensures all Vulkan resources are destroyed in the correct order.
impl Drop for Renderer { impl Drop for Renderer {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
// 1. Destroy the swapchain BEFORE the device it belongs to // Destroy the swapchain
self.swapchain_loader.destroy_swapchain(self.swapchain, None); self.swapchain_loader.destroy_swapchain(self.swapchain, None);
// 2. Destroy the logical device // Destroy image views
for &view in &self.swapchain_image_views {
self.device.destroy_image_view(view, None);
}
// Destroy the logical device
self.device.destroy_device(None); self.device.destroy_device(None);
// 3. Destroy the surface // Destroy the surface
self.surface_loader.destroy_surface(self.surface, None); self.surface_loader.destroy_surface(self.surface, None);
// 4. Destroy the debug messenger if we created one // Destroy the debug messenger if we created one
if let Some(utils) = &self.debug_utils { if let Some(utils) = &self.debug_utils {
utils.destroy_debug_utils_messenger(self.debug_messenger, None); utils.destroy_debug_utils_messenger(self.debug_messenger, None);
} }
// 5. Finally, destroy the instance // Destroy the instance
self.instance.destroy_instance(None); self.instance.destroy_instance(None);
} }
} }