vulkan_lib/vulkan-rs/src/surface.rs

81 lines
2.4 KiB
Rust
Raw Normal View History

2023-01-14 12:03:01 +00:00
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<Instance>,
surface: VkSurfaceKHR,
}
impl Surface {
pub fn from_vk_surface(surface: VkSurfaceKHR, instance: &Arc<Instance>) -> Arc<Surface> {
Arc::new(Surface {
external_source: true,
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) {
if !self.external_source {
self.instance.destroy_surface(self.surface)
}
}
}