use core::ptr::null_mut;
use raw_vulkan_handle::*;
use zstring::{ZStr, ZString};
use super::*;
#[repr(C)]
pub struct VkWindow {
win: NonNull<SDL_Window>,
init: Arc<SdlInit>,
}
impl Sdl {
#[inline]
pub fn create_vk_window(&self, args: CreateWinArgs<'_>) -> Result<VkWindow, SdlError> {
let title_null: String = alloc::format!("{}\0", args.title);
let win_p: *mut SDL_Window = unsafe {
SDL_CreateWindow(
title_null.as_ptr().cast(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
args.width,
args.height,
SDL_WINDOW_VULKAN.0 | args.window_flags().0,
)
};
match NonNull::new(win_p) {
Some(win) => Ok(VkWindow { win, init: self.init.clone() }),
None => Err(get_error()),
}
}
}
impl Drop for VkWindow {
#[inline]
fn drop(&mut self) {
unsafe { SDL_DestroyWindow(self.win.as_ptr()) }
}
}
impl Deref for VkWindow {
type Target = CommonWindow;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const Self).cast::<CommonWindow>() }
}
}
#[allow(non_camel_case_types)]
pub type PFN_vkVoidFunction = Option<unsafe extern "system" fn()>;
impl VkWindow {
#[inline]
#[allow(non_snake_case)]
pub fn get_vkGetInstanceProcAddr(
&self,
) -> Option<unsafe extern "system" fn(VkInstance, *const u8) -> PFN_vkVoidFunction> {
unsafe { core::mem::transmute(SDL_Vulkan_GetVkGetInstanceProcAddr()) }
}
#[inline]
pub fn get_instance_extensions(&self) -> Result<Vec<ZString>, SdlError> {
let mut count: c_uint = 0;
let success: bool =
unsafe { SDL_Vulkan_GetInstanceExtensions(self.win.as_ptr(), &mut count, null_mut()) }.into();
if !success {
return Err(get_error());
}
let mut buf: Vec<ZStr<'_>> = Vec::with_capacity(count.try_into().unwrap());
let success: bool = unsafe {
SDL_Vulkan_GetInstanceExtensions(self.win.as_ptr(), &mut count, buf.as_mut_ptr().cast())
}
.into();
if !success {
return Err(get_error());
}
unsafe {
buf.set_len(count.try_into().unwrap());
}
Ok(buf.into_iter().map(ZString::from).collect())
}
#[inline]
pub unsafe fn create_surface(&self, instance: VkInstance) -> Result<VkSurfaceKHR, SdlError> {
let mut surface = VkSurfaceKHR::default();
if unsafe { SDL_Vulkan_CreateSurface(self.win.as_ptr(), instance, &mut surface) }.into() {
Ok(surface)
} else {
Err(get_error())
}
}
#[inline]
pub fn get_drawable_size(&self) -> (i32, i32) {
let mut w = 0;
let mut h = 0;
unsafe { SDL_Vulkan_GetDrawableSize(self.win.as_ptr(), &mut w, &mut h) }
(w, h)
}
}