From 5b5a7cba54829ee593390fb9e4d47ed79d7b6c42 Mon Sep 17 00:00:00 2001 From: Janis Date: Sun, 5 Jan 2025 03:13:02 +0100 Subject: [PATCH] swapchain: use Image abstraction, add support to that for swapchain images --- crates/renderer/src/images.rs | 57 +++++++++++---- crates/renderer/src/lib.rs | 129 +++++++++++++++++++--------------- 2 files changed, 116 insertions(+), 70 deletions(-) diff --git a/crates/renderer/src/images.rs b/crates/renderer/src/images.rs index 2974a33..6e98988 100644 --- a/crates/renderer/src/images.rs +++ b/crates/renderer/src/images.rs @@ -129,16 +129,22 @@ define_device_owned_handle! { views: Mutex>, aliases: Mutex>>, parent: Option>, - } => |this| unsafe { - for &view in this.views.lock().values() { - this.inner.dev().dev().destroy_image_view(view, None); - } - if this.parent.is_none() { - // destroy image handle and allocation - this.inner.dev().alloc().destroy_image(this.handle(), this.alloc.as_mut().unwrap()); - } else { - // destroy image handle - this.inner.dev().dev().destroy_image(this.handle(), None); + is_swapchain_image:bool, + } => |this| if !this.is_swapchain_image { + unsafe { + for &view in this.views.lock().values() { + this.inner.dev().dev().destroy_image_view(view, None); + } + + let handle = this.handle(); + let dev = this.device().clone(); + if let Some(alloc) = this.alloc.as_mut() { + // destroy image handle and allocation + dev.alloc().destroy_image(handle, alloc); + } else { + // destroy image handle + dev.dev().destroy_image(handle, None); + } } } } @@ -152,6 +158,7 @@ impl PartialEq for Image { impl Image { pub fn new(device: Device, desc: ImageDesc) -> VkResult { + tracing::trace!("allocate new image with desc={desc:?}"); let ImageDesc { flags, name, @@ -209,6 +216,28 @@ impl Image { Mutex::new(HashMap::new()), Mutex::new(HashMap::new()), None, // aliased + false, + ) + } + + pub unsafe fn from_swapchain_image( + device: Device, + image: vk::Image, + name: Option>, + extent: vk::Extent3D, + format: vk::Format, + ) -> Result { + Self::construct( + device, + image, + name, + None, + extent, + format, + Mutex::new(HashMap::new()), + Mutex::new(HashMap::new()), + None, + true, ) } @@ -297,7 +326,9 @@ impl Image { .array_layers(array_layers) .mip_levels(mip_levels); - let alloc = self.get_alloc().unwrap(); + let alloc = self + .get_alloc() + .expect("no alloc associated with image. is this the framebuffer?"); let image = unsafe { let image = self.device().dev().create_image(info, None)?; @@ -311,6 +342,7 @@ impl Image { image }; + let parent = self.parent.clone().unwrap_or(self.clone()); let alias = Self::construct( self.device().clone(), image, @@ -320,7 +352,8 @@ impl Image { format, Mutex::new(HashMap::new()), Mutex::new(HashMap::new()), - Some(self.parent.clone().unwrap_or(self.clone())), + Some(parent.clone()), + parent.is_swapchain_image, )?; Ok(vacant.insert(Arc::new(alias)).clone()) } diff --git a/crates/renderer/src/lib.rs b/crates/renderer/src/lib.rs index 163c9e4..7f72be2 100644 --- a/crates/renderer/src/lib.rs +++ b/crates/renderer/src/lib.rs @@ -500,7 +500,7 @@ pub struct Swapchain { #[allow(unused)] color_space: vk::ColorSpaceKHR, format: vk::Format, - images: Vec, + images: Vec>, image_views: Vec, extent: vk::Extent2D, min_image_count: u32, @@ -579,7 +579,7 @@ struct SwapchainParams { pub struct SwapchainFrame { pub swapchain: Arc, pub index: u32, - pub image: vk::Image, + pub image: Arc, pub format: vk::Format, pub view: vk::ImageView, pub acquire: vk::Semaphore, @@ -712,26 +712,47 @@ impl Swapchain { ) }?; + let images = images + .iter() + .enumerate() + .map(|(i, image)| unsafe { + images::Image::from_swapchain_image( + device.clone(), + *image, + Some(format!("swapchain-{swapchain:?}-image-{i}").into()), + vk::Extent3D { + width: extent.width, + height: extent.height, + depth: 1, + }, + format, + ) + .inspect(|img| { + img.get_view(images::ImageViewDesc { + name: Some(format!("swapchain-{swapchain:?}-image-{i}-view").into()), + kind: vk::ImageViewType::TYPE_2D, + format, + aspect: vk::ImageAspectFlags::COLOR, + ..Default::default() + }); + }) + .map(|img| Arc::new(img)) + }) + .collect::>>()?; + let image_views = images .iter() - .map(|&image| { - let info = vk::ImageViewCreateInfo::default() - .image(image) - .view_type(vk::ImageViewType::TYPE_2D) - .format(format) - .components(vk::ComponentMapping::default()) - .subresource_range( - vk::ImageSubresourceRange::default() - .aspect_mask(vk::ImageAspectFlags::COLOR) - .base_mip_level(0) - .level_count(1) - .base_array_layer(0) - .layer_count(1), - ); - - unsafe { device.dev().create_image_view(&info, None) } + .enumerate() + .map(|(i, image)| { + image.get_view(images::ImageViewDesc { + name: Some(format!("swapchain-{swapchain:?}-image-{i}-view").into()), + kind: vk::ImageViewType::TYPE_2D, + format, + aspect: vk::ImageAspectFlags::COLOR, + ..Default::default() + }) }) - .collect::, _>>()?; + .collect::>>()?; let num_images = images.len() as u32; let inflight_frames = num_images - min_image_count; @@ -745,16 +766,15 @@ impl Swapchain { .inspect(|r| { #[cfg(debug_assertions)] { - let name = CString::new(format!( - "semaphore-{:x}_{i}-acquire", - swapchain.0.lock().as_raw() - )) - .unwrap(); - _ = device.debug_utils().set_debug_utils_object_name( - &vk::DebugUtilsObjectNameInfoEXT::default() - .object_handle(*r) - .object_name(&name), - ); + device + .debug_name_object( + *r, + &format!( + "semaphore-{:x}_{i}-acquire", + swapchain.0.lock().as_raw() + ), + ) + .unwrap(); } }) }) @@ -770,16 +790,15 @@ impl Swapchain { .inspect(|r| { #[cfg(debug_assertions)] { - let name = CString::new(format!( - "semaphore-{:x}_{i}-release", - swapchain.0.lock().as_raw() - )) - .unwrap(); - _ = device.debug_utils().set_debug_utils_object_name( - &vk::DebugUtilsObjectNameInfoEXT::default() - .object_handle(*r) - .object_name(&name), - ); + device + .debug_name_object( + *r, + &format!( + "semaphore-{:x}_{i}-release", + swapchain.0.lock().as_raw() + ), + ) + .unwrap(); } }) }) @@ -793,18 +812,12 @@ impl Swapchain { |r| { #[cfg(debug_assertions)] { - let name = CString::new(format!( - "fence-{:x}_{i}", - swapchain.0.lock().as_raw() - )) - .unwrap(); - unsafe { - _ = device.debug_utils().set_debug_utils_object_name( - &vk::DebugUtilsObjectNameInfoEXT::default() - .object_handle(r.fence()) - .object_name(&name), - ); - } + device + .debug_name_object( + r.fence(), + &format!("fence-{:x}_{i}", swapchain.0.lock().as_raw()), + ) + .unwrap(); } }, )?)) @@ -812,7 +825,7 @@ impl Swapchain { .collect::>>()? }; - tracing::debug!("fences: {fences:?}"); + tracing::trace!("fences: {fences:?}"); Ok(Self { device, @@ -865,7 +878,7 @@ impl Swapchain { ) .unwrap() as usize; - tracing::debug!(frame, "acquiring image for frame {frame}"); + tracing::trace!(frame, "acquiring image for frame {frame}"); async move { let fence = self.fences[frame].clone(); @@ -893,7 +906,7 @@ impl Swapchain { sync::FenceFuture::new(fence.clone()).await; let idx = idx as usize; - let image = self.images[idx]; + let image = self.images[idx].clone(); let view = self.image_views[idx]; Ok(( @@ -2516,7 +2529,7 @@ impl Renderer { let cmd = util::timed("record command buffer", || { let cmd = pool.alloc()?; cmd.image_barrier( - frame.image, + frame.image.handle(), vk::ImageAspectFlags::COLOR, vk::PipelineStageFlags2::TRANSFER, vk::AccessFlags2::empty(), @@ -2527,14 +2540,14 @@ impl Renderer { None, ); cmd.clear_color_image( - frame.image, + frame.image.handle(), frame.format, vk::ImageLayout::TRANSFER_DST_OPTIMAL, clear_color, &[images::SUBRESOURCERANGE_COLOR_ALL], ); cmd.image_barrier( - frame.image, + frame.image.handle(), vk::ImageAspectFlags::COLOR, vk::PipelineStageFlags2::TRANSFER, vk::AccessFlags2::TRANSFER_WRITE, @@ -2604,7 +2617,7 @@ impl Renderer { } cmd.image_barrier( - frame.image, + frame.image.handle(), vk::ImageAspectFlags::COLOR, vk::PipelineStageFlags2::FRAGMENT_SHADER, vk::AccessFlags2::SHADER_WRITE,