use crate::vulkan::{VkInstance, VkPhysicalDevice}; use ash::prelude::VkResult; use ash::vk; use std::sync::Arc; use winit::raw_window_handle::{HasDisplayHandle, HasWindowHandle}; pub struct SwapchainSupportDetails( pub Vec, pub vk::SurfaceCapabilitiesKHR, pub Vec, ); pub struct VkSurface { instance: Arc, pub(super) handle: vk::SurfaceKHR, } impl VkSurface { pub fn new(window: &crate::display::Window, instance: Arc) -> anyhow::Result { let window_handle = window .handle() .ok_or_else(|| anyhow::anyhow!("Window handle is not available."))?; let surface = unsafe { ash_window::create_surface( &instance.entry, &instance.handle, window_handle.display_handle()?.as_raw(), window_handle.window_handle()?.as_raw(), None, )? }; log::debug!("Surface created ({:?})", surface); Ok(Self { instance, handle: surface }) } pub fn physical_device_queue_supported( &self, physical_device: &VkPhysicalDevice, queue_index: u32, ) -> VkResult { unsafe { self.instance .surface_loader .get_physical_device_surface_support( physical_device.handle, queue_index, self.handle, ) } } pub fn get_physical_device_swapchain_support_details( &self, physical_device: &VkPhysicalDevice, ) -> VkResult { unsafe { let formats = self .instance .surface_loader .get_physical_device_surface_formats(physical_device.handle, self.handle)?; let capabilities = self .instance .surface_loader .get_physical_device_surface_capabilities(physical_device.handle, self.handle)?; let present_modes = self .instance .surface_loader .get_physical_device_surface_present_modes(physical_device.handle, self.handle)?; Ok(SwapchainSupportDetails( formats, capabilities, present_modes, )) } } } impl Drop for VkSurface { fn drop(&mut self) { unsafe { self.instance .surface_loader .destroy_surface(self.handle, None); } log::debug!("Surface destroyed ({:?})", self.handle); } }