94 lines
2.6 KiB
Rust
94 lines
2.6 KiB
Rust
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<vk::SurfaceFormatKHR>,
|
|
pub vk::SurfaceCapabilitiesKHR,
|
|
pub Vec<vk::PresentModeKHR>,
|
|
);
|
|
|
|
pub struct VkSurface {
|
|
instance: Arc<VkInstance>,
|
|
|
|
pub(super) handle: vk::SurfaceKHR,
|
|
}
|
|
|
|
impl VkSurface {
|
|
pub fn new(window: &crate::display::Window, instance: Arc<VkInstance>) -> anyhow::Result<Self> {
|
|
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<bool> {
|
|
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<SwapchainSupportDetails> {
|
|
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);
|
|
}
|
|
}
|