76 lines
2.3 KiB
Rust
76 lines
2.3 KiB
Rust
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 {
|
|
instance: Arc<Instance>,
|
|
surface: VkSurfaceKHR,
|
|
}
|
|
|
|
impl Surface {
|
|
pub fn from_vk_surface(surface: VkSurfaceKHR, instance: &Arc<Instance>) -> Arc<Surface> {
|
|
Arc::new(Surface {
|
|
instance: instance.clone(),
|
|
surface,
|
|
})
|
|
}
|
|
|
|
pub fn capabilities(&self, device: &Arc<Device>) -> Result<VkSurfaceCapabilitiesKHR> {
|
|
self.instance.physical_device_surface_capabilities(
|
|
device.physical_device().vk_handle(),
|
|
self.surface,
|
|
)
|
|
}
|
|
|
|
pub fn format_colorspace(
|
|
&self,
|
|
device: &Arc<Device>,
|
|
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<Device>) -> Result<Vec<VkPresentModeKHR>> {
|
|
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) {
|
|
self.instance.destroy_surface(self.surface)
|
|
}
|
|
}
|