From 96cb0031747c2ae647950d0c0acad34c8d2f241e Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Wed, 13 Nov 2024 13:56:22 +0100 Subject: [PATCH] Refactor vk_swapchain --- src/vulkan/vk_render_context.rs | 8 +++--- src/vulkan/vk_surface.rs | 42 +++++++++++------------------ src/vulkan/vk_swapchain.rs | 47 +++++++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 32 deletions(-) diff --git a/src/vulkan/vk_render_context.rs b/src/vulkan/vk_render_context.rs index d7d6541..cc47472 100644 --- a/src/vulkan/vk_render_context.rs +++ b/src/vulkan/vk_render_context.rs @@ -5,7 +5,7 @@ pub struct VkRenderContext { instance: VkInstance, surface: VkSurface, device: VkDevice, - swapchain: VkSwapchain + swapchain: VkSwapchain, } impl VkRenderContext { @@ -28,11 +28,11 @@ impl VkRenderContext { let device = VkDevice::new_graphics_device(&instance, &physical_device, queue_family_index) .expect("Unable to create device"); - let swapchain = surface.create_swapchain( + let mut swapchain = surface.create_swapchain( &window, &instance, &device, - &physical_device + &physical_device, ).expect("Unable to create swapchain"); // let present_queue = device.get_device_queue(0); @@ -41,7 +41,7 @@ impl VkRenderContext { instance, surface, device, - swapchain + swapchain, }) } } \ No newline at end of file diff --git a/src/vulkan/vk_surface.rs b/src/vulkan/vk_surface.rs index 3540999..363d1a1 100644 --- a/src/vulkan/vk_surface.rs +++ b/src/vulkan/vk_surface.rs @@ -1,11 +1,11 @@ +use crate::display::Window; 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, - surface: vk::SurfaceKHR, + pub(super) surface: vk::SurfaceKHR, } impl VkSurface { @@ -68,7 +68,9 @@ impl VkSurface { 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() + let surface_format = surface_formats + .first() + .and_then(|f| Some(*f)) .ok_or_else(|| anyhow::anyhow!("No available surface formats"))?; log::debug!(target: LOG_TARGET, "Selected surface format: {surface_format:?}"); @@ -116,30 +118,18 @@ impl VkSurface { .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( + let mut swapchain = VkSwapchain::new( swapchain_loader, - Some(swapchain) - )) + desired_image_count, + surface_format, + surface_resolution, + present_mode, + pre_transform, + ); + + swapchain.create_swapchain(&self)?; + + Ok(swapchain) } } diff --git a/src/vulkan/vk_swapchain.rs b/src/vulkan/vk_swapchain.rs index f0eff16..fc6ee25 100644 --- a/src/vulkan/vk_swapchain.rs +++ b/src/vulkan/vk_swapchain.rs @@ -1,20 +1,63 @@ +use crate::vulkan::{VkSurface, LOG_TARGET}; +use ash::prelude::VkResult; use ash::vk; +use ash::vk::{Extent2D, PresentModeKHR, SurfaceFormatKHR, SurfaceTransformFlagsKHR, SwapchainKHR}; pub struct VkSwapchain { swapchain_loader: ash::khr::swapchain::Device, swapchain: Option, + + desired_image_count: u32, + surface_format: SurfaceFormatKHR, + surface_resolution: Extent2D, + present_mode: PresentModeKHR, + pre_transform: SurfaceTransformFlagsKHR, } impl VkSwapchain { pub fn new( swapchain_loader: ash::khr::swapchain::Device, - swapchain: Option, + desired_image_count: u32, + surface_format: SurfaceFormatKHR, + surface_resolution: Extent2D, + present_mode: PresentModeKHR, + pre_transform: SurfaceTransformFlagsKHR, ) -> Self { Self { swapchain_loader, - swapchain + desired_image_count, + surface_format, + surface_resolution, + present_mode, + pre_transform, + swapchain: None, } } + + pub fn create_swapchain(&mut self, surface: &VkSurface) -> VkResult<()> { + let swapchain_create_info = vk::SwapchainCreateInfoKHR::default() + .surface(surface.surface) + .min_image_count(self.desired_image_count) + .image_color_space(self.surface_format.color_space) + .image_format(self.surface_format.format) + .image_extent(self.surface_resolution) + .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) + .image_sharing_mode(vk::SharingMode::EXCLUSIVE) + .pre_transform(self.pre_transform) + .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) + .present_mode(self.present_mode) + .clipped(true) + .image_array_layers(1); + + let swapchain = unsafe { + self.swapchain_loader.create_swapchain(&swapchain_create_info, None)? + }; + log::debug!(target: LOG_TARGET, "Swapchain created : {swapchain_create_info:#?}"); + + self.swapchain = Some(swapchain); + + Ok(()) + } } impl Drop for VkSwapchain {