Add swapchain (work in progress)
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 0s

This commit is contained in:
Florian RICHER 2024-11-12 22:01:08 +01:00
parent caa79270db
commit ee8b886aec
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
7 changed files with 139 additions and 13 deletions

View file

@ -1,6 +1,7 @@
use crate::vulkan::{VkPhysicalDevice, LOG_TARGET};
use crate::vulkan::{VkDevice, VkInstance, VkPhysicalDevice, VkSwapchain, LOG_TARGET};
use ash::prelude::VkResult;
use ash::vk;
use crate::display::Window;
pub struct VkSurface {
surface_loader: ash::khr::surface::Instance,
@ -54,6 +55,92 @@ impl VkSurface {
)
}
}
pub fn create_swapchain(
&self,
window: &Window,
instance: &VkInstance,
device: &VkDevice,
physical_device: &VkPhysicalDevice,
) -> anyhow::Result<VkSwapchain> {
log::debug!(target: LOG_TARGET, "Creating swapchain");
let surface_formats = self.get_physical_device_surface_formats(physical_device)?;
log::debug!(target: LOG_TARGET, "Supported surface formats by physical device: {surface_formats:#?}");
let surface_format = surface_formats.first()
.ok_or_else(|| anyhow::anyhow!("No available surface formats"))?;
log::debug!(target: LOG_TARGET, "Selected surface format: {surface_format:?}");
let surface_capabilities = self.get_physical_device_surface_capabilities(physical_device)?;
log::debug!(target: LOG_TARGET, "Surface capabilities: {surface_capabilities:#?}");
let mut desired_image_count = surface_capabilities.min_image_count + 1;
if surface_capabilities.max_image_count > 0
&& desired_image_count > surface_capabilities.max_image_count
{
desired_image_count = surface_capabilities.max_image_count;
}
log::debug!(target: LOG_TARGET, "Selected surface image count: {desired_image_count}");
let window_size = window.size()
.ok_or_else(|| anyhow::anyhow!("Window size is not valid"))?
.to_physical::<u32>(1.0);
log::debug!(target: LOG_TARGET, "Window size: {window_size:?}");
let surface_resolution = match surface_capabilities.current_extent.width {
u32::MAX => vk::Extent2D {
width: window_size.width,
height: window_size.height,
},
_ => surface_capabilities.current_extent,
};
log::debug!(target: LOG_TARGET, "Surface resolution: {surface_resolution:?}");
let pre_transform = if surface_capabilities
.supported_transforms
.contains(vk::SurfaceTransformFlagsKHR::IDENTITY)
{
vk::SurfaceTransformFlagsKHR::IDENTITY
} else {
surface_capabilities.current_transform
};
let present_modes = self
.get_physical_device_surface_present_modes(physical_device)?;
let present_mode = present_modes
.iter()
.cloned()
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO);
let swapchain_loader = ash::khr::swapchain::Device::new(&instance.handle, &device.handle);
let swapchain_create_info = vk::SwapchainCreateInfoKHR::default()
.surface(self.surface)
.min_image_count(desired_image_count)
.image_color_space(surface_format.color_space)
.image_format(surface_format.format)
.image_extent(surface_resolution)
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
.pre_transform(pre_transform)
.composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE)
.present_mode(present_mode)
.clipped(true)
.image_array_layers(1);
log::debug!(target: LOG_TARGET, "Swapchain info: {swapchain_create_info:#?}");
let swapchain = unsafe {
swapchain_loader.create_swapchain(&swapchain_create_info, None)?
};
log::debug!(target: LOG_TARGET, "Swapchain created");
Ok(VkSwapchain::new(
swapchain_loader,
Some(swapchain)
))
}
}
impl Drop for VkSurface {