use std::{ffi::CString, mem, ptr};
use ash::vk::{self, Handle};
use crate::*;
impl Instance {
#[inline]
pub fn set_name(&self, name: &str) -> Result<()> {
if let Some(fp) = self.exts().ext_debug_utils.as_ref() {
let name = CString::new(name).unwrap();
let info = sys::DebugUtilsObjectNameInfoEXT {
ty: sys::DebugUtilsObjectNameInfoEXT::TYPE,
next: ptr::null(),
object_type: ObjectType::INSTANCE,
object_handle: self.as_raw().into_raw(),
object_name: name.as_ptr(),
};
unsafe {
cvt((fp.set_debug_utils_object_name)(self.as_raw(), &info))?;
}
}
Ok(())
}
#[inline]
pub fn properties(&self) -> Result<InstanceProperties> {
unsafe {
let mut p = sys::InstanceProperties {
ty: sys::InstanceProperties::TYPE,
..mem::zeroed()
};
cvt((self.fp().get_instance_properties)(self.as_raw(), &mut p))?;
Ok(InstanceProperties {
runtime_version: p.runtime_version,
runtime_name: fixed_str(&p.runtime_name).into(),
})
}
}
#[inline]
pub fn result_to_string(&self, result: sys::Result) -> Result<String> {
unsafe {
let mut s = [0; sys::MAX_RESULT_STRING_SIZE];
cvt((self.fp().result_to_string)(
self.as_raw(),
result,
s.as_mut_ptr(),
))?;
Ok(fixed_str(&s).into())
}
}
#[inline]
pub fn structure_type_to_string(&self, ty: StructureType) -> Result<String> {
unsafe {
let mut s = [0; sys::MAX_STRUCTURE_NAME_SIZE];
cvt((self.fp().structure_type_to_string)(
self.as_raw(),
ty,
s.as_mut_ptr(),
))?;
Ok(fixed_str(&s).into())
}
}
#[inline]
pub fn system(&self, form_factor: FormFactor) -> Result<SystemId> {
let info = sys::SystemGetInfo {
ty: sys::SystemGetInfo::TYPE,
next: ptr::null_mut(),
form_factor,
};
let mut out = SystemId::NULL;
unsafe {
cvt((self.fp().get_system)(self.as_raw(), &info, &mut out))?;
}
Ok(out)
}
#[inline]
pub fn system_properties(&self, system: SystemId) -> Result<SystemProperties> {
unsafe {
let mut p = sys::SystemProperties {
ty: sys::SystemProperties::TYPE,
..mem::zeroed()
};
cvt((self.fp().get_system_properties)(
self.as_raw(),
system,
&mut p,
))?;
Ok(SystemProperties {
system_id: p.system_id,
vendor_id: p.vendor_id,
system_name: fixed_str(&p.system_name).into(),
graphics_properties: p.graphics_properties,
tracking_properties: SystemTrackingProperties {
orientation_tracking: p.tracking_properties.orientation_tracking.into(),
position_tracking: p.tracking_properties.position_tracking.into(),
},
})
}
}
#[inline]
pub unsafe fn string_to_path(&self, string: &str) -> Result<Path> {
let string = CString::new(string).map_err(|_| sys::Result::ERROR_PATH_FORMAT_INVALID)?;
let mut out = Path::NULL;
cvt((self.fp().string_to_path)(
self.as_raw(),
string.as_ptr(),
&mut out,
))?;
Ok(out)
}
#[inline]
pub fn path_to_string(&self, path: Path) -> Result<String> {
get_str(|input, output, buf| unsafe {
(self.fp().path_to_string)(self.as_raw(), path, input, output, buf)
})
}
#[inline]
pub fn vulkan_instance_extensions(&self, system: SystemId) -> Result<String> {
get_str(|input, output, buf| unsafe {
(self.vulkan().get_vulkan_instance_extensions)(
self.as_raw(),
system,
input,
output,
buf,
)
})
}
#[inline]
pub fn vulkan_device_extensions(&self, system: SystemId) -> Result<String> {
get_str(|input, output, buf| unsafe {
(self.vulkan().get_vulkan_device_extensions)(self.as_raw(), system, input, output, buf)
})
}
#[inline]
pub fn vulkan_graphics_device(
&self,
system: SystemId,
vk_instance: vk::Instance,
) -> Result<vk::PhysicalDevice> {
let mut out = vk::PhysicalDevice::null();
unsafe {
cvt((self.vulkan().get_vulkan_graphics_device)(
self.as_raw(),
system,
vk_instance.as_raw() as _,
&mut out as *mut _ as _,
))?;
}
Ok(out)
}
pub fn graphics_requirements<G: Graphics>(&self, system: SystemId) -> Result<G::Requirements> {
G::requirements(self, system)
}
#[inline]
pub unsafe fn create_session<G: Graphics>(
&self,
system: SystemId,
info: &G::SessionCreateInfo,
) -> Result<Session<G>> {
G::create_session(self.clone(), system, info)
}
#[inline]
pub fn create_session_headless(&self, system: SystemId) -> Result<Session<Headless>> {
unsafe { self.create_session(system, &()) }
}
#[inline]
pub fn poll_event<'a>(&self, storage: &'a mut EventDataBuffer) -> Result<Option<Event<'a>>> {
unsafe {
let storage: *mut EventDataBuffer = storage;
loop {
let status = cvt((self.fp().poll_event)(self.as_raw(), &mut (*storage).inner))?;
if status == sys::Result::EVENT_UNAVAILABLE {
return Ok(None);
}
debug_assert_eq!(status, sys::Result::SUCCESS);
if let x @ Some(_) = Event::from_raw(&(*storage).inner) {
return Ok(x);
}
}
}
}
#[inline]
pub fn enumerate_view_configurations(
&self,
system: SystemId,
) -> Result<Vec<ViewConfigurationType>> {
get_arr(|cap, count, buf| unsafe {
(self.fp().enumerate_view_configurations)(self.as_raw(), system, cap, count, buf)
})
}
#[inline]
pub fn view_configuration_properties(
&self,
system: SystemId,
ty: ViewConfigurationType,
) -> Result<ViewConfigurationProperties> {
let mut out;
unsafe {
out = sys::ViewConfigurationProperties {
ty: sys::ViewConfigurationProperties::TYPE,
next: ptr::null_mut(),
..mem::uninitialized()
};
cvt((self.fp().get_view_configuration_properties)(
self.as_raw(),
system,
ty,
&mut out,
))?;
}
Ok(ViewConfigurationProperties {
view_configuration_type: out.view_configuration_type,
fov_mutable: out.fov_mutable != sys::FALSE,
})
}
#[inline]
pub fn enumerate_view_configuration_views(
&self,
system: SystemId,
ty: ViewConfigurationType,
) -> Result<Vec<ViewConfigurationView>> {
let views = get_arr_init(
unsafe {
sys::ViewConfigurationView {
ty: sys::ViewConfigurationView::TYPE,
next: ptr::null_mut(),
..mem::uninitialized()
}
},
|capacity, count, buf| unsafe {
(self.fp().enumerate_view_configuration_views)(
self.as_raw(),
system,
ty,
capacity,
count,
buf as *mut _,
)
},
)?;
Ok(views
.into_iter()
.map(|x| ViewConfigurationView {
recommended_image_rect_width: x.recommended_image_rect_width,
max_image_rect_width: x.max_image_rect_width,
recommended_image_rect_height: x.recommended_image_rect_height,
max_image_rect_height: x.max_image_rect_height,
recommended_swapchain_sample_count: x.recommended_swapchain_sample_count,
max_swapchain_sample_count: x.max_swapchain_sample_count,
})
.collect())
}
#[inline]
pub fn enumerate_environment_blend_modes(
&self,
system: SystemId,
) -> Result<Vec<EnvironmentBlendMode>> {
get_arr(|cap, count, buf| unsafe {
(self.fp().enumerate_environment_blend_modes)(self.as_raw(), system, cap, count, buf)
})
}
pub(crate) fn vulkan(&self) -> &raw::VulkanEnableKHR {
self.exts().khr_vulkan_enable.as_ref().unwrap()
}
pub(crate) fn opengl(&self) -> &raw::OpenglEnableKHR {
self.exts().khr_opengl_enable.as_ref().unwrap()
}
}
#[derive(Debug, Clone)]
pub struct InstanceProperties {
pub runtime_version: u32,
pub runtime_name: String,
}
#[derive(Clone)]
pub struct SystemProperties {
pub system_id: SystemId,
pub vendor_id: u32,
pub system_name: String,
pub graphics_properties: SystemGraphicsProperties,
pub tracking_properties: SystemTrackingProperties,
}
#[derive(Debug, Copy, Clone)]
pub struct SystemTrackingProperties {
pub orientation_tracking: bool,
pub position_tracking: bool,
}
#[derive(Debug, Copy, Clone)]
pub struct ViewConfigurationProperties {
pub view_configuration_type: ViewConfigurationType,
pub fov_mutable: bool,
}
#[derive(Debug, Copy, Clone)]
pub struct ViewConfigurationView {
pub recommended_image_rect_width: u32,
pub max_image_rect_width: u32,
pub recommended_image_rect_height: u32,
pub max_image_rect_height: u32,
pub recommended_swapchain_sample_count: u32,
pub max_swapchain_sample_count: u32,
}
pub struct EventDataBuffer {
inner: sys::EventDataBuffer,
}
impl EventDataBuffer {
pub fn new() -> Self {
Self {
inner: sys::EventDataBuffer {
ty: sys::EventDataBuffer::TYPE,
next: ptr::null_mut(),
..unsafe { mem::uninitialized() }
}
}
}
}