swapchain: use Image abstraction, add support to that for swapchain images
This commit is contained in:
parent
2fc7d3e179
commit
5b5a7cba54
|
@ -129,16 +129,22 @@ define_device_owned_handle! {
|
||||||
views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>,
|
views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>,
|
||||||
aliases: Mutex<HashMap<ImageDesc, Arc<Image>>>,
|
aliases: Mutex<HashMap<ImageDesc, Arc<Image>>>,
|
||||||
parent: Option<Arc<Image>>,
|
parent: Option<Arc<Image>>,
|
||||||
} => |this| unsafe {
|
is_swapchain_image:bool,
|
||||||
|
} => |this| if !this.is_swapchain_image {
|
||||||
|
unsafe {
|
||||||
for &view in this.views.lock().values() {
|
for &view in this.views.lock().values() {
|
||||||
this.inner.dev().dev().destroy_image_view(view, None);
|
this.inner.dev().dev().destroy_image_view(view, None);
|
||||||
}
|
}
|
||||||
if this.parent.is_none() {
|
|
||||||
|
let handle = this.handle();
|
||||||
|
let dev = this.device().clone();
|
||||||
|
if let Some(alloc) = this.alloc.as_mut() {
|
||||||
// destroy image handle and allocation
|
// destroy image handle and allocation
|
||||||
this.inner.dev().alloc().destroy_image(this.handle(), this.alloc.as_mut().unwrap());
|
dev.alloc().destroy_image(handle, alloc);
|
||||||
} else {
|
} else {
|
||||||
// destroy image handle
|
// destroy image handle
|
||||||
this.inner.dev().dev().destroy_image(this.handle(), None);
|
dev.dev().destroy_image(handle, None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,6 +158,7 @@ impl PartialEq for Image {
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
pub fn new(device: Device, desc: ImageDesc) -> VkResult<Self> {
|
pub fn new(device: Device, desc: ImageDesc) -> VkResult<Self> {
|
||||||
|
tracing::trace!("allocate new image with desc={desc:?}");
|
||||||
let ImageDesc {
|
let ImageDesc {
|
||||||
flags,
|
flags,
|
||||||
name,
|
name,
|
||||||
|
@ -209,6 +216,28 @@ impl Image {
|
||||||
Mutex::new(HashMap::new()),
|
Mutex::new(HashMap::new()),
|
||||||
Mutex::new(HashMap::new()),
|
Mutex::new(HashMap::new()),
|
||||||
None, // aliased
|
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)
|
.array_layers(array_layers)
|
||||||
.mip_levels(mip_levels);
|
.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 = unsafe {
|
||||||
let image = self.device().dev().create_image(info, None)?;
|
let image = self.device().dev().create_image(info, None)?;
|
||||||
|
@ -311,6 +342,7 @@ impl Image {
|
||||||
image
|
image
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let parent = self.parent.clone().unwrap_or(self.clone());
|
||||||
let alias = Self::construct(
|
let alias = Self::construct(
|
||||||
self.device().clone(),
|
self.device().clone(),
|
||||||
image,
|
image,
|
||||||
|
@ -320,7 +352,8 @@ impl Image {
|
||||||
format,
|
format,
|
||||||
Mutex::new(HashMap::new()),
|
Mutex::new(HashMap::new()),
|
||||||
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())
|
Ok(vacant.insert(Arc::new(alias)).clone())
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,7 +500,7 @@ pub struct Swapchain {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
color_space: vk::ColorSpaceKHR,
|
color_space: vk::ColorSpaceKHR,
|
||||||
format: vk::Format,
|
format: vk::Format,
|
||||||
images: Vec<vk::Image>,
|
images: Vec<Arc<images::Image>>,
|
||||||
image_views: Vec<vk::ImageView>,
|
image_views: Vec<vk::ImageView>,
|
||||||
extent: vk::Extent2D,
|
extent: vk::Extent2D,
|
||||||
min_image_count: u32,
|
min_image_count: u32,
|
||||||
|
@ -579,7 +579,7 @@ struct SwapchainParams {
|
||||||
pub struct SwapchainFrame {
|
pub struct SwapchainFrame {
|
||||||
pub swapchain: Arc<Swapchain>,
|
pub swapchain: Arc<Swapchain>,
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
pub image: vk::Image,
|
pub image: Arc<images::Image>,
|
||||||
pub format: vk::Format,
|
pub format: vk::Format,
|
||||||
pub view: vk::ImageView,
|
pub view: vk::ImageView,
|
||||||
pub acquire: vk::Semaphore,
|
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
|
let image_views = images
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&image| {
|
.enumerate()
|
||||||
let info = vk::ImageViewCreateInfo::default()
|
.map(|(i, image)| {
|
||||||
.image(image)
|
image.get_view(images::ImageViewDesc {
|
||||||
.view_type(vk::ImageViewType::TYPE_2D)
|
name: Some(format!("swapchain-{swapchain:?}-image-{i}-view").into()),
|
||||||
.format(format)
|
kind: vk::ImageViewType::TYPE_2D,
|
||||||
.components(vk::ComponentMapping::default())
|
format,
|
||||||
.subresource_range(
|
aspect: vk::ImageAspectFlags::COLOR,
|
||||||
vk::ImageSubresourceRange::default()
|
..Default::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) }
|
|
||||||
})
|
})
|
||||||
.collect::<core::result::Result<Vec<vk::ImageView>, _>>()?;
|
})
|
||||||
|
.collect::<VkResult<Vec<_>>>()?;
|
||||||
|
|
||||||
let num_images = images.len() as u32;
|
let num_images = images.len() as u32;
|
||||||
let inflight_frames = num_images - min_image_count;
|
let inflight_frames = num_images - min_image_count;
|
||||||
|
@ -745,16 +766,15 @@ impl Swapchain {
|
||||||
.inspect(|r| {
|
.inspect(|r| {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
let name = CString::new(format!(
|
device
|
||||||
|
.debug_name_object(
|
||||||
|
*r,
|
||||||
|
&format!(
|
||||||
"semaphore-{:x}_{i}-acquire",
|
"semaphore-{:x}_{i}-acquire",
|
||||||
swapchain.0.lock().as_raw()
|
swapchain.0.lock().as_raw()
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
_ = device.debug_utils().set_debug_utils_object_name(
|
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
|
||||||
.object_handle(*r)
|
|
||||||
.object_name(&name),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -770,16 +790,15 @@ impl Swapchain {
|
||||||
.inspect(|r| {
|
.inspect(|r| {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
let name = CString::new(format!(
|
device
|
||||||
|
.debug_name_object(
|
||||||
|
*r,
|
||||||
|
&format!(
|
||||||
"semaphore-{:x}_{i}-release",
|
"semaphore-{:x}_{i}-release",
|
||||||
swapchain.0.lock().as_raw()
|
swapchain.0.lock().as_raw()
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
_ = device.debug_utils().set_debug_utils_object_name(
|
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
|
||||||
.object_handle(*r)
|
|
||||||
.object_name(&name),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -793,18 +812,12 @@ impl Swapchain {
|
||||||
|r| {
|
|r| {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
let name = CString::new(format!(
|
device
|
||||||
"fence-{:x}_{i}",
|
.debug_name_object(
|
||||||
swapchain.0.lock().as_raw()
|
r.fence(),
|
||||||
))
|
&format!("fence-{:x}_{i}", swapchain.0.lock().as_raw()),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unsafe {
|
|
||||||
_ = device.debug_utils().set_debug_utils_object_name(
|
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
|
||||||
.object_handle(r.fence())
|
|
||||||
.object_name(&name),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)?))
|
)?))
|
||||||
|
@ -812,7 +825,7 @@ impl Swapchain {
|
||||||
.collect::<VkResult<Vec<_>>>()?
|
.collect::<VkResult<Vec<_>>>()?
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::debug!("fences: {fences:?}");
|
tracing::trace!("fences: {fences:?}");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
device,
|
device,
|
||||||
|
@ -865,7 +878,7 @@ impl Swapchain {
|
||||||
)
|
)
|
||||||
.unwrap() as usize;
|
.unwrap() as usize;
|
||||||
|
|
||||||
tracing::debug!(frame, "acquiring image for frame {frame}");
|
tracing::trace!(frame, "acquiring image for frame {frame}");
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let fence = self.fences[frame].clone();
|
let fence = self.fences[frame].clone();
|
||||||
|
@ -893,7 +906,7 @@ impl Swapchain {
|
||||||
sync::FenceFuture::new(fence.clone()).await;
|
sync::FenceFuture::new(fence.clone()).await;
|
||||||
|
|
||||||
let idx = idx as usize;
|
let idx = idx as usize;
|
||||||
let image = self.images[idx];
|
let image = self.images[idx].clone();
|
||||||
let view = self.image_views[idx];
|
let view = self.image_views[idx];
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
|
@ -2516,7 +2529,7 @@ impl<W> Renderer<W> {
|
||||||
let cmd = util::timed("record command buffer", || {
|
let cmd = util::timed("record command buffer", || {
|
||||||
let cmd = pool.alloc()?;
|
let cmd = pool.alloc()?;
|
||||||
cmd.image_barrier(
|
cmd.image_barrier(
|
||||||
frame.image,
|
frame.image.handle(),
|
||||||
vk::ImageAspectFlags::COLOR,
|
vk::ImageAspectFlags::COLOR,
|
||||||
vk::PipelineStageFlags2::TRANSFER,
|
vk::PipelineStageFlags2::TRANSFER,
|
||||||
vk::AccessFlags2::empty(),
|
vk::AccessFlags2::empty(),
|
||||||
|
@ -2527,14 +2540,14 @@ impl<W> Renderer<W> {
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
cmd.clear_color_image(
|
cmd.clear_color_image(
|
||||||
frame.image,
|
frame.image.handle(),
|
||||||
frame.format,
|
frame.format,
|
||||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||||
clear_color,
|
clear_color,
|
||||||
&[images::SUBRESOURCERANGE_COLOR_ALL],
|
&[images::SUBRESOURCERANGE_COLOR_ALL],
|
||||||
);
|
);
|
||||||
cmd.image_barrier(
|
cmd.image_barrier(
|
||||||
frame.image,
|
frame.image.handle(),
|
||||||
vk::ImageAspectFlags::COLOR,
|
vk::ImageAspectFlags::COLOR,
|
||||||
vk::PipelineStageFlags2::TRANSFER,
|
vk::PipelineStageFlags2::TRANSFER,
|
||||||
vk::AccessFlags2::TRANSFER_WRITE,
|
vk::AccessFlags2::TRANSFER_WRITE,
|
||||||
|
@ -2604,7 +2617,7 @@ impl<W> Renderer<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.image_barrier(
|
cmd.image_barrier(
|
||||||
frame.image,
|
frame.image.handle(),
|
||||||
vk::ImageAspectFlags::COLOR,
|
vk::ImageAspectFlags::COLOR,
|
||||||
vk::PipelineStageFlags2::FRAGMENT_SHADER,
|
vk::PipelineStageFlags2::FRAGMENT_SHADER,
|
||||||
vk::AccessFlags2::SHADER_WRITE,
|
vk::AccessFlags2::SHADER_WRITE,
|
||||||
|
|
Loading…
Reference in a new issue