pub use winit;
pub mod ash;
pub use imgui;
pub use imgui_sys;
pub use vk_mem;
pub mod imguiash;
pub use glsl_to_spirv_macros::*;
pub use glsl_to_spirv_macros_impl::GLSLEmbedImpl;
use std::os::raw::c_char;
use winit::window::Window;
use crate::ash::{extensions::khr, prelude::VkResult, vk};
pub mod vk_helper;
pub trait WindowExt {
fn is_presentation_supported(
&self,
entry: &ash::Entry,
instance: &ash::Instance,
physical_device: vk::PhysicalDevice,
queue_family_indices: u32,
) -> VkResult<bool>;
fn get_required_extensions(&self) -> VkResult<Vec<*const c_char>>;
fn create_surface(
&self,
entry: &ash::Entry,
instance: &ash::Instance,
flags: vk::Flags,
allocator: Option<&vk::AllocationCallbacks>,
) -> VkResult<vk::SurfaceKHR>;
}
impl WindowExt for Window {
fn is_presentation_supported(
&self,
entry: &ash::Entry,
instance: &ash::Instance,
physical_device: vk::PhysicalDevice,
queue_family_indices: u32,
) -> VkResult<bool> {
match get_backend(self)? {
Backend::Xlib { .. } => Ok(true), Backend::Wayland { display, .. } => {
let surface = ash::extensions::khr::WaylandSurface::new(entry, instance);
Ok(unsafe {
surface.get_physical_device_wayland_presentation_support(
physical_device,
queue_family_indices,
display,
)
})
}
Backend::Win32 { .. } => {
let surface = ash::extensions::khr::Win32Surface::new(entry, instance);
Ok(unsafe {
surface.get_physical_device_win32_presentation_support(
physical_device,
queue_family_indices,
)
})
}
}
}
fn get_required_extensions(&self) -> VkResult<Vec<*const c_char>> {
match get_backend(self)? {
Backend::Xlib { .. } => Ok(vec![
khr::Surface::name().as_ptr(),
khr::XlibSurface::name().as_ptr(),
]),
Backend::Wayland { .. } => Ok(vec![
khr::Surface::name().as_ptr(),
khr::WaylandSurface::name().as_ptr(),
]),
Backend::Win32 { .. } => Ok(vec![
khr::Surface::name().as_ptr(),
khr::Win32Surface::name().as_ptr(),
]),
}
}
fn create_surface(
&self,
entry: &ash::Entry,
instance: &ash::Instance,
flags: vk::Flags,
allocator: Option<&vk::AllocationCallbacks>,
) -> VkResult<vk::SurfaceKHR> {
match get_backend(self)? {
Backend::Xlib { display, window } => {
let create_info = vk::XlibSurfaceCreateInfoKHR {
flags: vk::XlibSurfaceCreateFlagsKHR::from_raw(flags),
dpy: display,
window,
..Default::default()
};
unsafe {
khr::XlibSurface::new(entry, instance)
.create_xlib_surface(&create_info, allocator)
}
}
Backend::Wayland { display, surface } => {
let create_info = vk::WaylandSurfaceCreateInfoKHR {
flags: vk::WaylandSurfaceCreateFlagsKHR::from_raw(flags),
display,
surface,
..Default::default()
};
unsafe {
khr::WaylandSurface::new(entry, instance)
.create_wayland_surface(&create_info, allocator)
}
}
Backend::Win32 { hinstance, hwnd } => {
let create_info = vk::Win32SurfaceCreateInfoKHR {
flags: vk::Win32SurfaceCreateFlagsKHR::from_raw(flags),
hinstance,
hwnd,
..Default::default()
};
unsafe {
khr::Win32Surface::new(entry, instance)
.create_win32_surface(&create_info, allocator)
}
}
}
}
}
#[allow(dead_code)]
enum Backend<'a> {
Xlib {
display: &'a mut vk::Display,
window: vk::Window,
},
Wayland {
display: &'a mut vk::wl_display,
surface: &'a mut vk::wl_surface,
},
Win32 {
hinstance: vk::HINSTANCE,
hwnd: vk::HWND,
},
}
#[allow(unused_variables)]
#[allow(unreachable_code)]
fn get_backend(window: &Window) -> VkResult<Backend> {
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "openbsd"
))]
{
use winit::platform::unix::WindowExtUnix;
if let (Some(display), Some(window)) = (window.xlib_display(), window.xlib_window()) {
return if !display.is_null() {
Ok(Backend::Xlib {
display: unsafe { &mut *(display as *mut vk::Display) },
window: window as _,
})
} else {
Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY)
};
}
if let (Some(display), Some(surface)) = (window.wayland_display(), window.wayland_surface())
{
return if !(display.is_null() || surface.is_null()) {
Ok(Backend::Wayland {
display: unsafe { &mut *(display as *mut vk::wl_display) },
surface: unsafe { &mut *(surface as *mut vk::wl_surface) },
})
} else {
Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY)
};
}
}
#[cfg(target_os = "windows")]
{
use winit::platform::windows::WindowExtWindows;
return Ok(Backend::Win32 {
hinstance: ::std::ptr::null_mut(), hwnd: window.hwnd() as _,
});
}
Err(vk::Result::ERROR_INITIALIZATION_FAILED)
}