swapchain: use Image abstraction, add support to that for swapchain images

This commit is contained in:
Janis 2025-01-05 03:13:02 +01:00
parent 2fc7d3e179
commit 5b5a7cba54
2 changed files with 116 additions and 70 deletions

View file

@ -129,16 +129,22 @@ define_device_owned_handle! {
views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>,
aliases: Mutex<HashMap<ImageDesc, Arc<Image>>>,
parent: Option<Arc<Image>>,
} => |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<Self> {
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<Cow<'static, str>>,
extent: vk::Extent3D,
format: vk::Format,
) -> Result<Image, vk::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())
}

View file

@ -500,7 +500,7 @@ pub struct Swapchain {
#[allow(unused)]
color_space: vk::ColorSpaceKHR,
format: vk::Format,
images: Vec<vk::Image>,
images: Vec<Arc<images::Image>>,
image_views: Vec<vk::ImageView>,
extent: vk::Extent2D,
min_image_count: u32,
@ -579,7 +579,7 @@ struct SwapchainParams {
pub struct SwapchainFrame {
pub swapchain: Arc<Swapchain>,
pub index: u32,
pub image: vk::Image,
pub image: Arc<images::Image>,
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::<VkResult<Vec<_>>>()?;
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::<core::result::Result<Vec<vk::ImageView>, _>>()?;
.collect::<VkResult<Vec<_>>>()?;
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::<VkResult<Vec<_>>>()?
};
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<W> Renderer<W> {
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<W> Renderer<W> {
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<W> Renderer<W> {
}
cmd.image_barrier(
frame.image,
frame.image.handle(),
vk::ImageAspectFlags::COLOR,
vk::PipelineStageFlags2::FRAGMENT_SHADER,
vk::AccessFlags2::SHADER_WRITE,