use raw_window_handle::RawDisplayHandle;
use crate::vk;
#[cfg(all(
any(target_os = "macos", target_os = "ios"),
not(feature = "raw-window-metal")
))]
compile_error!("Feature raw-window-metal should be enabled along raw-window-handle when compiling on MacOS/iOS");
pub fn enumerate_required_extensions(
display_handle: &RawDisplayHandle,
) -> vk::Result<&'static [vk::InstanceExtensionName]> {
let extensions = match display_handle {
RawDisplayHandle::Windows(_) => &[vk::KHR_SURFACE.name, vk::KHR_WIN32_SURFACE.name],
RawDisplayHandle::Wayland(_) => &[vk::KHR_SURFACE.name, vk::KHR_WAYLAND_SURFACE.name],
RawDisplayHandle::Xlib(_) => &[vk::KHR_SURFACE.name, vk::KHR_XLIB_SURFACE.name],
RawDisplayHandle::Xcb(_) => &[vk::KHR_SURFACE.name, vk::KHR_XCB_SURFACE.name],
RawDisplayHandle::Android(_) => &[vk::KHR_SURFACE.name, vk::KHR_ANDROID_SURFACE.name],
RawDisplayHandle::AppKit(_) | RawDisplayHandle::UiKit(_) => {
&[vk::KHR_SURFACE.name, vk::EXT_METAL_SURFACE.name]
}
_ => return Err(vk::Status::ErrorExtensionNotPresent),
};
Ok(extensions)
}
pub mod raw {
use std::os::raw::c_void;
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
use crate::vk;
pub unsafe fn create_surface(
instance: &vk::raw::Instance,
allocator: Option<&vk::AllocationCallbacks>,
dispatcher: &vk::CommandsDispatcher,
display_handle: &RawDisplayHandle,
window_handle: &RawWindowHandle,
) -> vk::Result<vk::raw::SurfaceKHR> {
match (display_handle, window_handle) {
(RawDisplayHandle::Windows(_), RawWindowHandle::Win32(window)) => {
let surface_desc = vk::Win32SurfaceCreateInfoKHR::default()
.hwnd(window.hwnd.get() as *const c_void)
.hinstance(
window
.hinstance
.ok_or(vk::Status::ErrorInitializationFailed)?
.get() as *const c_void,
);
vk::raw::create_win32_surface_khr(instance, &surface_desc, allocator, dispatcher)
}
(RawDisplayHandle::Wayland(display), RawWindowHandle::Wayland(window)) => {
let surface_desc = vk::WaylandSurfaceCreateInfoKHR::default()
.display(unsafe { Some(display.display.cast().as_ref()) })
.surface(unsafe { Some(window.surface.cast().as_ref()) });
vk::raw::create_wayland_surface_khr(instance, &surface_desc, allocator, dispatcher)
}
(RawDisplayHandle::Xlib(display), RawWindowHandle::Xlib(window)) => {
let surface_desc = vk::XlibSurfaceCreateInfoKHR::default()
.dpy(unsafe {
Some(
display
.display
.ok_or(vk::Status::ErrorInitializationFailed)?
.cast()
.as_ref(),
)
})
.window(window.window);
vk::raw::create_xlib_surface_khr(instance, &surface_desc, allocator, dispatcher)
}
(RawDisplayHandle::Xcb(display), RawWindowHandle::Xcb(window)) => {
let surface_desc = vk::XcbSurfaceCreateInfoKHR::default()
.connection(unsafe {
Some(
display
.connection
.ok_or(vk::Status::ErrorInitializationFailed)?
.cast()
.as_ref(),
)
})
.window(window.window.get());
vk::raw::create_xcb_surface_khr(instance, &surface_desc, allocator, dispatcher)
}
(RawDisplayHandle::Android(_), RawWindowHandle::AndroidNdk(window)) => {
let surface_desc = vk::AndroidSurfaceCreateInfoKHR::default()
.window(unsafe { Some(window.a_native_window.cast().as_ref()) });
vk::raw::create_android_surface_khr(instance, &surface_desc, allocator, dispatcher)
}
#[cfg(all(target_os = "macos", feature = "raw-window-metal"))]
(RawDisplayHandle::AppKit(_), RawWindowHandle::AppKit(window)) => {
use raw_window_metal::Layer;
let layer = unsafe { Layer::from_ns_view(window.ns_view) };
let surface_desc = vk::MetalSurfaceCreateInfoEXT::default()
.layer(Some(unsafe { layer.as_ptr().cast().as_ref() }));
vk::raw::create_metal_surface_ext(instance, &surface_desc, allocator, dispatcher)
}
#[cfg(all(target_os = "ios", feature = "raw-window-metal"))]
(RawDisplayHandle::UiKit(_), RawWindowHandle::UiKit(window)) => {
use raw_window_metal::Layer;
let layer = unsafe { Layer::from_ui_view(window.ui_view) };
let surface_desc = vk::MetalSurfaceCreateInfoEXT::default()
.layer(Some(unsafe { layer.as_ptr().cast().as_ref() }));
vk::raw::create_metal_surface_ext(instance, &surface_desc, allocator, dispatcher)
}
_ => Err(vk::Status::ErrorExtensionNotPresent),
}
}
}
pub mod rs {
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
use crate::{vk, Allocator, Dispatcher};
pub fn create_surface<D: Dispatcher, A: Allocator>(
instance: &vk::rs::Instance<D, A>,
display_handle: &RawDisplayHandle,
window_handle: &RawWindowHandle,
) -> vk::Result<vk::rs::SurfaceKHR> {
unsafe {
super::raw::create_surface(
instance,
instance.get_allocator().get_allocation_callbacks().as_ref(),
instance.get_dispatcher().get_command_dispatcher(),
display_handle,
window_handle,
)
.map(|surface| vk::rs::SurfaceKHR::from_inner(surface))
}
}
}