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;
#[cfg(feature = "__OLD__")]
pub mod vk_helper {
use crate::ash::version::DeviceV1_0;
use crate::ash::{vk, Device};
use crate::vk_mem::{error, Allocation, AllocationCreateInfo, AllocationInfo, Allocator};
use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
#[derive(Clone)]
pub struct Buffer {
pub allocator: Rc<RefCell<Allocator>>,
pub buffer: ::ash::vk::Buffer,
pub allocation: Allocation,
pub allocation_info: AllocationInfo,
}
impl fmt::Debug for Buffer {
fn fmt(&self, __arg_0: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Buffer {
allocator: _,
buffer: ref __self_0_0,
allocation: ref __self_0_1,
allocation_info: ref __self_0_2,
} => {
let mut builder = __arg_0.debug_struct("Buffer");
let _ = builder.field("buffer", &&(*__self_0_0));
let _ = builder.field("allocation", &&(*__self_0_1));
let _ = builder.field("allocation_info", &&(*__self_0_2));
builder.finish()
}
}
}
}
impl Buffer {
pub fn new(
allocator: Rc<RefCell<Allocator>>,
buffer_create_info: &::ash::vk::BufferCreateInfo,
allocation_create_info: &AllocationCreateInfo,
) -> error::Result<Buffer> {
let (buffer, allocation, allocation_info) = allocator
.borrow_mut()
.create_buffer(buffer_create_info, allocation_create_info)?;
Ok(Buffer {
allocator,
buffer,
allocation,
allocation_info,
})
}
}
impl Drop for Buffer {
fn drop(&mut self) {
self.allocator
.borrow_mut()
.destroy_buffer(self.buffer, &self.allocation)
.unwrap();
}
}
#[derive(Clone)]
pub struct Image {
pub allocator: Rc<RefCell<Allocator>>,
pub image: ::ash::vk::Image,
pub allocation: Allocation,
pub allocation_info: AllocationInfo,
}
impl fmt::Debug for Image {
fn fmt(&self, __arg_0: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Image {
allocator: _,
image: ref __self_0_0,
allocation: ref __self_0_1,
allocation_info: ref __self_0_2,
} => {
let mut builder = __arg_0.debug_struct("Image");
let _ = builder.field("image", &&(*__self_0_0));
let _ = builder.field("allocation", &&(*__self_0_1));
let _ = builder.field("allocation_info", &&(*__self_0_2));
builder.finish()
}
}
}
}
impl Image {
pub fn new(
allocator: Rc<RefCell<Allocator>>,
image_create_info: &::ash::vk::ImageCreateInfo,
allocation_create_info: &AllocationCreateInfo,
) -> error::Result<Image> {
let (image, allocation, allocation_info) = allocator
.borrow_mut()
.create_image(image_create_info, allocation_create_info)?;
Ok(Image {
allocator,
image,
allocation,
allocation_info,
})
}
}
impl Drop for Image {
fn drop(&mut self) {
self.allocator
.borrow_mut()
.destroy_image(self.image, &self.allocation)
.unwrap();
}
}
#[derive(Clone)]
pub struct Pipeline {
pub device: Device,
pub pipeline: vk::Pipeline,
}
impl fmt::Debug for Pipeline {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.pipeline)
}
}
impl Drop for Pipeline {
fn drop(&mut self) {
unsafe { self.device.destroy_pipeline(self.pipeline, None) };
}
}
}
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)
}