rust_vulkan_test/src/vulkan/vk_surface.rs

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);
}
}