use crate::prelude::*; use anyhow::Result; use std::sync::Arc; const UNORM_FORMATS: [VkFormat; 2] = [VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM]; #[derive(Debug)] pub struct Surface { external_source: bool, instance: Arc, surface: VkSurfaceKHR, } impl Surface { pub fn from_vk_surface(surface: VkSurfaceKHR, instance: &Arc) -> Arc { Arc::new(Surface { external_source: true, instance: instance.clone(), surface, }) } pub fn capabilities(&self, device: &Arc) -> Result { self.instance.physical_device_surface_capabilities( device.physical_device().vk_handle(), self.surface, ) } pub fn format_colorspace( &self, device: &Arc, prefered_format: VkFormat, ) -> Result<(VkFormat, VkColorSpaceKHR)> { let surface_formats = self .instance .physical_device_surface_formats(device.physical_device().vk_handle(), self.surface)?; // if there is a single undefined format, assume the preferred mode if (surface_formats.len() == 1) && (surface_formats[0].format == VK_FORMAT_UNDEFINED) { return Ok((prefered_format, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)); } // look for prefered_format for surface_format in &surface_formats { if surface_format.format == prefered_format { return Ok((surface_format.format, surface_format.colorSpace)); } } // prefer UNORM formats for surface_format in &surface_formats { for unorm_format in &UNORM_FORMATS { if *unorm_format == surface_format.format { return Ok((surface_format.format, surface_format.colorSpace)); } } } // if nothing was found, take the first one Ok((surface_formats[0].format, surface_formats[0].colorSpace)) } pub fn present_modes(&self, device: &Arc) -> Result> { self.instance .physical_device_present_modes(device.physical_device().vk_handle(), self.surface) } } impl_vk_handle!(Surface, VkSurfaceKHR, surface); impl Drop for Surface { fn drop(&mut self) { if !self.external_source { self.instance.destroy_surface(self.surface) } } }