use ash::vk;
use log::info;
use super::GraphicsDevice;
use crate::core::{
FrameBuffer, FrameBufferBuilder, FrameSync, Image, ImageBuilder, ImageView, ImageViewBuilder, RenderPass, Surface, Swapchain, SwapchainBuilder,
VulkanResult,
};
pub struct WindowManager {
pub(crate) resolution: vk::Extent2D,
pub(crate) frame_sync: Vec<FrameSync>,
pub(crate) frame_buffers: Vec<FrameBuffer>,
pub(crate) image_views: Vec<ImageView>,
pub(crate) current_frame: usize,
pub(crate) depth_image: Image,
pub(crate) depth_view: ImageView,
pub(crate) render_pass: RenderPass,
pub(crate) surface: Surface,
pub(crate) swapchain: Swapchain,
}
impl WindowManager {
pub fn resize(&mut self, device: &GraphicsDevice, width: u32, height: u32) -> VulkanResult<()> {
profiling::scope!("WindowManager::resize");
info!("New size: {:?}", (width, height));
unsafe { device.device_wait_idle().expect("Error wait idle") };
let caps = self
.surface
.get_physical_device_surface_capabilities(*device.phys_dev)?;
let formats = self
.surface
.get_physical_device_surface_formats(*device.phys_dev)?;
let extent = caps.current_extent;
let transforms = caps.current_transform;
let format_priority = [vk::Format::R8G8B8A8_SRGB];
let color_space_priority = [
#[cfg(target_os = "android")]
vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT,
vk::ColorSpaceKHR::SRGB_NONLINEAR,
];
let mut format = vk::Format::R8G8B8A8_SRGB;
let mut color_space = vk::ColorSpaceKHR::SRGB_NONLINEAR;
for (f, c) in format_priority.iter().zip(color_space_priority.iter()) {
for j in &formats {
if *f == j.format && *c == j.color_space {
format = j.format;
color_space = j.color_space;
}
}
}
let swapchain = SwapchainBuilder::new(device)
.old_swapchain(self.swapchain.raw)
.min_image_count(caps.min_image_count)
.surface(&self.surface)
.present_mode(vk::PresentModeKHR::FIFO)
.instance(&device.instance)
.color_space(color_space)
.extent(extent)
.format(format)
.build()?;
let depth_image = ImageBuilder::depth(device, vk::Format::D32_SFLOAT, caps.current_extent).build()?;
let depth_view = ImageViewBuilder::depth(device, vk::Format::D32_SFLOAT, depth_image.raw).build()?;
let mut image_views = vec![];
for i in swapchain.get_swapchain_images()? {
let image_view = ImageViewBuilder::new_2d(device, vk::Format::R8G8B8A8_SRGB, i).build()?;
image_views.push(image_view);
}
let mut frame_buffers = vec![];
for i in &image_views {
let frame_buffer = FrameBufferBuilder::new(device)
.render_pass(self.render_pass.raw)
.attachments(&[
i.raw,
depth_view.raw
])
.extent(caps.current_extent)
.layers(1)
.build()?;
frame_buffers.push(frame_buffer);
}
self.depth_view.destroy(device);
self.depth_view = depth_view;
self.depth_image.destroy(device);
self.depth_image = depth_image;
for i in &self.image_views {
i.destroy(device);
}
self.image_views = image_views;
for i in &self.frame_buffers {
i.destroy(device);
}
self.frame_buffers = frame_buffers;
self.swapchain.destroy();
self.swapchain = swapchain;
self.resolution = caps.current_extent;
Ok(())
}
}