use crate::{extensions::khr_surface, utils::VulkanResult, vk1_0, InstanceLoader};
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle};
use std::os::raw::c_char;
pub unsafe fn create_surface<RawHandle>(
instance: &InstanceLoader,
window_handle: &RawHandle,
allocation_callbacks: Option<&vk1_0::AllocationCallbacks>,
) -> VulkanResult<khr_surface::SurfaceKHR> where RawHandle: HasRawWindowHandle + HasRawDisplayHandle {
match (window_handle.raw_window_handle(), window_handle.raw_display_handle()) {
(RawWindowHandle::Wayland(window_handle), RawDisplayHandle::Wayland(display_handle)) => {
use crate::extensions::khr_wayland_surface;
let create_info = khr_wayland_surface::WaylandSurfaceCreateInfoKHR {
display: display_handle.display,
surface: window_handle.surface,
..Default::default()
};
instance.create_wayland_surface_khr(&create_info, allocation_callbacks)
}
(RawWindowHandle::Xlib(window_handle), RawDisplayHandle::Xlib(display_handle)) => {
use crate::extensions::khr_xlib_surface;
let create_info = khr_xlib_surface::XlibSurfaceCreateInfoKHR {
dpy: display_handle.display as *mut _,
window: window_handle.window as _,
..Default::default()
};
instance.create_xlib_surface_khr(&create_info, allocation_callbacks)
}
(RawWindowHandle::Xcb(window_handle), RawDisplayHandle::Xcb(display_handle)) => {
use crate::extensions::khr_xcb_surface;
let create_info = khr_xcb_surface::XcbSurfaceCreateInfoKHR {
connection: display_handle.connection as *mut _,
window: window_handle.window,
..Default::default()
};
instance.create_xcb_surface_khr(&create_info, allocation_callbacks)
}
(RawWindowHandle::AndroidNdk(window_handle), _) => {
use crate::extensions::khr_android_surface;
let create_info = khr_android_surface::AndroidSurfaceCreateInfoKHR {
window: window_handle.a_native_window as _,
..Default::default()
};
instance.create_android_surface_khr(&create_info, allocation_callbacks)
}
#[cfg(any(target_os = "macos"))]
(RawWindowHandle::AppKit(window_handle), _) => {
use crate::{extensions::ext_metal_surface, vk1_0};
use raw_window_metal::{appkit, Layer};
let layer = match appkit::metal_layer_from_handle(window_handle) {
Layer::Existing(layer) | Layer::Allocated(layer) => layer as *mut _,
Layer::None => {
return VulkanResult::new_err(vk1_0::Result::ERROR_INITIALIZATION_FAILED)
}
};
let create_info = ext_metal_surface::MetalSurfaceCreateInfoEXT {
p_layer: layer,
..Default::default()
};
instance.create_metal_surface_ext(&create_info, allocation_callbacks)
}
#[cfg(any(target_os = "ios"))]
(RawWindowHandle::UiKit(window_handle), _) => {
use crate::{extensions::ext_metal_surface, vk1_0};
use raw_window_metal::{uikit, Layer};
let layer = match uikit::metal_layer_from_handle(window_handle) {
Layer::Existing(layer) | Layer::Allocated(layer) => layer as *mut _,
Layer::None => {
return VulkanResult::new_err(vk1_0::Result::ERROR_INITIALIZATION_FAILED)
}
};
let create_info = ext_metal_surface::MetalSurfaceCreateInfoEXT {
p_layer: layer,
..Default::default()
};
instance.create_metal_surface_ext(&create_info, allocation_callbacks)
}
(RawWindowHandle::Win32(handle), _) => {
use crate::extensions::khr_win32_surface;
let create_info = khr_win32_surface::Win32SurfaceCreateInfoKHR {
hinstance: handle.hinstance,
hwnd: handle.hwnd,
..Default::default()
};
instance.create_win32_surface_khr(&create_info, allocation_callbacks)
}
_ => VulkanResult::new_err(vk1_0::Result::ERROR_EXTENSION_NOT_PRESENT), }
}
pub fn enumerate_required_extensions(
window_handle: &impl HasRawWindowHandle,
) -> VulkanResult<Vec<*const c_char>> {
let extensions = match window_handle.raw_window_handle() {
RawWindowHandle::Wayland(_) => vec![
khr_surface::KHR_SURFACE_EXTENSION_NAME,
crate::extensions::khr_wayland_surface::KHR_WAYLAND_SURFACE_EXTENSION_NAME,
],
RawWindowHandle::Xlib(_) => vec![
khr_surface::KHR_SURFACE_EXTENSION_NAME,
crate::extensions::khr_xlib_surface::KHR_XLIB_SURFACE_EXTENSION_NAME,
],
RawWindowHandle::Xcb(_) => vec![
khr_surface::KHR_SURFACE_EXTENSION_NAME,
crate::extensions::khr_xcb_surface::KHR_XCB_SURFACE_EXTENSION_NAME,
],
RawWindowHandle::AndroidNdk(_) => vec![
khr_surface::KHR_SURFACE_EXTENSION_NAME,
crate::extensions::khr_android_surface::KHR_ANDROID_SURFACE_EXTENSION_NAME,
],
RawWindowHandle::AppKit(_) | RawWindowHandle::UiKit(_) => vec![
khr_surface::KHR_SURFACE_EXTENSION_NAME,
crate::extensions::ext_metal_surface::EXT_METAL_SURFACE_EXTENSION_NAME,
],
RawWindowHandle::Win32(_) => vec![
khr_surface::KHR_SURFACE_EXTENSION_NAME,
crate::extensions::khr_win32_surface::KHR_WIN32_SURFACE_EXTENSION_NAME,
],
_ => return VulkanResult::new_err(vk1_0::Result::ERROR_EXTENSION_NOT_PRESENT), };
VulkanResult::new_ok(extensions)
}