Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 71 additions & 30 deletions generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ impl Parser {
let struct_name = attr(attrs, "name").unwrap();
let mut members = Vec::new();
let mut ty = None;
let mut mut_next = false;
let mut next = None;
loop {
use XmlEvent::*;
match self.reader.next().expect("failed to parse XML") {
Expand All @@ -558,8 +558,8 @@ impl Parser {
let m = self.parse_var("member", &attributes);
if m.name == "type" && m.ty == "XrStructureType" {
ty = attr(&attributes, "values").map(|x| x.into());
} else if m.name == "next" && !m.is_const {
mut_next = true;
} else if m.name == "next" {
next = Some(m.is_const);
}
members.push(m);
}
Expand Down Expand Up @@ -594,7 +594,7 @@ impl Parser {
members,
ty,
extension: None,
mut_next,
next,
},
);
}
Expand Down Expand Up @@ -1037,6 +1037,50 @@ impl Parser {
}
});

let traits = quote! {
pub trait XrType {
const TYPE: StructureType;
}

/// # Safety
///
/// Implementers must ensure that T is indeed an XR In Structure. Failing do do so may
/// cause UB, as this trait assumes T is at least as large as BaseInStructure.
pub unsafe trait XrInType: XrType {
#[inline]
/// Construct a partially-initialized value suitable for passing to OpenXR
fn base_in(next: *const BaseInStructure) -> MaybeUninit<Self> where Self: Sized {
let mut x = MaybeUninit::<Self>::uninit();
unsafe {
(x.as_mut_ptr() as *mut BaseInStructure).write(BaseInStructure {
ty: Self::TYPE,
next,
});
}
x
}
}

/// # Safety
///
/// Implementers must ensure that T is indeed an XR Out Structure. Failing do do so may
/// cause UB, as this trait assumes T is at least as large as BaseOutStructure.
pub unsafe trait XrOutType: XrType {
/// Construct a partially-initialized value suitable for passing to OpenXR
#[inline]
fn base_out(next: *mut BaseOutStructure) -> MaybeUninit<Self> where Self: Sized {
let mut x = MaybeUninit::<Self>::uninit();
unsafe {
(x.as_mut_ptr() as *mut BaseOutStructure).write(BaseOutStructure {
ty: Self::TYPE,
next,
});
}
x
}
}
};

let structs = self.structs.iter().map(|(name, s)| {
let ident = xr_ty_name(name);
let members = s.members.iter().map(|m| {
Expand All @@ -1060,37 +1104,33 @@ impl Parser {
format!("See {}", self.doc_link(name))
};
let conditions = conditions(name, s.extension.as_ref().map(|x| &x[..]));
let ty = if let Some(ref ty) = s.ty {
let conditions2 = conditions.clone();
let ty = xr_enum_value_name("XrStructureType", ty);
let out = if s.mut_next {
quote! {
/// Construct a partially-initialized value suitable for passing to OpenXR
#[inline]
pub fn out(next: *mut BaseOutStructure) -> MaybeUninit<Self> {
let mut x = MaybeUninit::<Self>::uninit();
unsafe {
(x.as_mut_ptr() as *mut BaseOutStructure).write(BaseOutStructure {
ty: Self::TYPE,
next,
});
}
x
}
}
} else {
quote! {}

let impls = if let Some(ref ty) = s.ty {
let in_out = match s.next {
Some(false) => quote! {
#conditions
unsafe impl XrOutType for #ident { }
},
Some(true) => quote! {
#conditions
unsafe impl XrInType for #ident { }
},
None => quote! {},
};

let ty = xr_enum_value_name("XrStructureType", ty);
quote! {
#conditions2
impl #ident {
pub const TYPE: StructureType = StructureType::#ty;
#out
#conditions
impl XrType for #ident {
const TYPE: StructureType = StructureType::#ty;
}

#in_out
}
} else {
quote! {}
};

let meta = self.compute_meta(name, s);
let derives = if (meta.has_pointer || meta.has_array) && meta.has_unprintable {
quote! { #[derive(Copy, Clone)] }
Expand All @@ -1107,7 +1147,7 @@ impl Parser {
pub struct #ident {
#(#members)*
}
#ty
#impls
}
});

Expand Down Expand Up @@ -1207,6 +1247,7 @@ impl Parser {
#(#enums)*
#(#bitmasks)*
#(#handles)*
#traits
#(#structs)*

/// Function pointer prototypes
Expand Down Expand Up @@ -2064,7 +2105,7 @@ struct Struct {
members: Vec<Member>,
extension: Option<Rc<str>>,
ty: Option<String>,
mut_next: bool,
next: Option<bool>, // some if it exists, true if it is const
}

#[derive(Debug, Clone)]
Expand Down
8 changes: 4 additions & 4 deletions openxr/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Action<Posef> {
subaction_path,
};
let out = unsafe {
let mut out = sys::ActionStatePose::out(ptr::null_mut());
let mut out = sys::ActionStatePose::base_out(ptr::null_mut());
cvt((self.fp().get_action_state_pose)(
session.as_raw(),
&info,
Expand Down Expand Up @@ -197,7 +197,7 @@ impl ActionInput for bool {
subaction_path,
};
unsafe {
let mut out = sys::ActionStateBoolean::out(ptr::null_mut());
let mut out = sys::ActionStateBoolean::base_out(ptr::null_mut());
cvt((action.fp().get_action_state_boolean)(
session.as_raw(),
&info,
Expand Down Expand Up @@ -231,7 +231,7 @@ impl ActionInput for f32 {
subaction_path,
};
unsafe {
let mut out = sys::ActionStateFloat::out(ptr::null_mut());
let mut out = sys::ActionStateFloat::base_out(ptr::null_mut());
cvt((action.fp().get_action_state_float)(
session.as_raw(),
&info,
Expand Down Expand Up @@ -265,7 +265,7 @@ impl ActionInput for Vector2f {
subaction_path,
};
unsafe {
let mut out = sys::ActionStateVector2f::out(ptr::null_mut());
let mut out = sys::ActionStateVector2f::base_out(ptr::null_mut());
cvt((action.fp().get_action_state_vector2f)(
session.as_raw(),
&info,
Expand Down
4 changes: 2 additions & 2 deletions openxr/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl Entry {
pub fn enumerate_extensions(&self) -> Result<ExtensionSet> {
unsafe {
let exts = get_arr_init(
sys::ExtensionProperties::out(ptr::null_mut()),
sys::ExtensionProperties::base_out(ptr::null_mut()),
|cap, count, buf| {
(self.fp().enumerate_instance_extension_properties)(
ptr::null(),
Expand All @@ -237,7 +237,7 @@ impl Entry {
pub fn enumerate_layers(&self) -> Result<Vec<ApiLayerProperties>> {
unsafe {
let layers = get_arr_init(
sys::ApiLayerProperties::out(ptr::null_mut()),
sys::ApiLayerProperties::base_out(ptr::null_mut()),
|cap, count, buf| (self.fp().enumerate_api_layer_properties)(cap, count, buf as _),
)?;
Ok(layers
Expand Down
2 changes: 1 addition & 1 deletion openxr/src/graphics/d3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl Graphics for D3D11 {

fn requirements(inst: &Instance, system: SystemId) -> Result<Requirements> {
let out = unsafe {
let mut x = sys::GraphicsRequirementsD3D11KHR::out(ptr::null_mut());
let mut x = sys::GraphicsRequirementsD3D11KHR::base_out(ptr::null_mut());
cvt((inst.d3d11().get_d3d11_graphics_requirements)(
inst.as_raw(),
system,
Expand Down
2 changes: 1 addition & 1 deletion openxr/src/graphics/opengl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl Graphics for OpenGL {

fn requirements(inst: &Instance, system: SystemId) -> Result<Requirements> {
let out = unsafe {
let mut x = sys::GraphicsRequirementsOpenGLKHR::out(ptr::null_mut());
let mut x = sys::GraphicsRequirementsOpenGLKHR::base_out(ptr::null_mut());
cvt((inst.opengl().get_open_gl_graphics_requirements)(
inst.as_raw(),
system,
Expand Down
2 changes: 1 addition & 1 deletion openxr/src/graphics/vulkan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl Graphics for Vulkan {

fn requirements(instance: &Instance, system: SystemId) -> Result<Requirements> {
let out = unsafe {
let mut x = sys::GraphicsRequirementsVulkanKHR::out(ptr::null_mut());
let mut x = sys::GraphicsRequirementsVulkanKHR::base_out(ptr::null_mut());
let fp = if instance.exts().khr_vulkan_enable2.is_some() {
instance.vulkan().get_vulkan_graphics_requirements2
} else {
Expand Down
8 changes: 4 additions & 4 deletions openxr/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ impl Instance {
#[inline]
pub fn supports_hand_tracking(&self, system: SystemId) -> Result<bool> {
unsafe {
let mut hand = sys::SystemHandTrackingPropertiesEXT::out(ptr::null_mut());
let mut p = sys::SystemProperties::out(&mut hand as *mut _ as _);
let mut hand = sys::SystemHandTrackingPropertiesEXT::base_out(ptr::null_mut());
let mut p = sys::SystemProperties::base_out(&mut hand as *mut _ as _);
cvt((self.fp().get_system_properties)(
self.as_raw(),
system,
Expand Down Expand Up @@ -439,7 +439,7 @@ impl Instance {
ty: ViewConfigurationType,
) -> Result<ViewConfigurationProperties> {
let out = unsafe {
let mut x = sys::ViewConfigurationProperties::out(ptr::null_mut());
let mut x = sys::ViewConfigurationProperties::base_out(ptr::null_mut());
cvt((self.fp().get_view_configuration_properties)(
self.as_raw(),
system,
Expand All @@ -461,7 +461,7 @@ impl Instance {
ty: ViewConfigurationType,
) -> Result<Vec<ViewConfigurationView>> {
let views = get_arr_init(
sys::ViewConfigurationView::out(ptr::null_mut()),
sys::ViewConfigurationView::base_out(ptr::null_mut()),
|capacity, count, buf| unsafe {
(self.fp().enumerate_view_configuration_views)(
self.as_raw(),
Expand Down
3 changes: 2 additions & 1 deletion openxr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
use std::os::raw::c_char;

pub use sys::{
self, Duration, Path, SystemId, Time, Version, CURRENT_API_VERSION, FREQUENCY_UNSPECIFIED,
self, Duration, Path, SystemId, Time, Version, XrOutType, XrType, CURRENT_API_VERSION,
FREQUENCY_UNSPECIFIED,
};

mod generated;
Expand Down
22 changes: 12 additions & 10 deletions openxr/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ impl<G> Session<G> {
space: space.as_raw(),
};
let (flags, raw) = unsafe {
let mut out = sys::ViewState::out(ptr::null_mut());
let raw = get_arr_init(sys::View::out(ptr::null_mut()), |cap, count, buf| {
let mut out = sys::ViewState::base_out(ptr::null_mut());
let raw = get_arr_init(sys::View::base_out(ptr::null_mut()), |cap, count, buf| {
(self.fp().locate_views)(
self.as_raw(),
&info,
Expand All @@ -178,7 +178,7 @@ impl<G> Session<G> {
#[inline]
pub fn current_interaction_profile(&self, top_level_user_path: Path) -> Result<Path> {
unsafe {
let mut out = sys::InteractionProfileState::out(ptr::null_mut());
let mut out = sys::InteractionProfileState::base_out(ptr::null_mut());
cvt((self.fp().get_current_interaction_profile)(
self.as_raw(),
top_level_user_path,
Expand Down Expand Up @@ -549,7 +549,7 @@ impl FrameWaiter {
#[inline]
pub fn wait(&mut self) -> Result<FrameState> {
let out = unsafe {
let mut x = sys::FrameState::out(ptr::null_mut());
let mut x = sys::FrameState::base_out(ptr::null_mut());
cvt((self.session.instance.fp().wait_frame)(
self.session.handle,
ptr::null(),
Expand All @@ -576,13 +576,14 @@ impl FrameWaiter {
let mut vec = Vec::new();
vec.resize(
count as usize,
sys::SecondaryViewConfigurationStateMSFT::out(ptr::null_mut()),
sys::SecondaryViewConfigurationStateMSFT::base_out(ptr::null_mut()),
);
let out = unsafe {
let mut secondary = sys::SecondaryViewConfigurationFrameStateMSFT::out(ptr::null_mut());
let mut secondary =
sys::SecondaryViewConfigurationFrameStateMSFT::base_out(ptr::null_mut());
(*secondary.as_mut_ptr()).view_configuration_count = count;
(*secondary.as_mut_ptr()).view_configuration_states = vec.as_mut_ptr() as *mut _;
let mut x = sys::FrameState::out(&mut secondary as *mut _ as *mut _);
let mut x = sys::FrameState::base_out(&mut secondary as *mut _ as *mut _);
cvt((self.session.instance.fp().wait_frame)(
self.session.handle,
ptr::null(),
Expand Down Expand Up @@ -617,14 +618,15 @@ impl FrameWaiter {
/// There must only be a single enabled secondary view
#[inline]
pub fn wait_secondary(&mut self) -> Result<(FrameState, SecondaryViewState)> {
let mut state = [sys::SecondaryViewConfigurationStateMSFT::out(
let mut state = [sys::SecondaryViewConfigurationStateMSFT::base_out(
ptr::null_mut(),
)];
let out = unsafe {
let mut secondary = sys::SecondaryViewConfigurationFrameStateMSFT::out(ptr::null_mut());
let mut secondary =
sys::SecondaryViewConfigurationFrameStateMSFT::base_out(ptr::null_mut());
(*secondary.as_mut_ptr()).view_configuration_count = 1;
(*secondary.as_mut_ptr()).view_configuration_states = state.as_mut_ptr() as *mut _;
let mut x = sys::FrameState::out(&mut secondary as *mut _ as *mut _);
let mut x = sys::FrameState::base_out(&mut secondary as *mut _ as *mut _);
cvt((self.session.instance.fp().wait_frame)(
self.session.handle,
ptr::null(),
Expand Down
6 changes: 3 additions & 3 deletions openxr/src/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl Space {
assert_eq!(&*self.session as *const session::SessionInner, &*base.session as *const session::SessionInner,
"`self` and `base` must have been created, allocated, or retrieved from the same `Session`");
unsafe {
let mut x = sys::SpaceLocation::out(ptr::null_mut());
let mut x = sys::SpaceLocation::base_out(ptr::null_mut());
cvt((self.fp().locate_space)(
self.as_raw(),
base.as_raw(),
Expand All @@ -103,8 +103,8 @@ impl Space {
assert_eq!(&*self.session as *const session::SessionInner, &*base.session as *const session::SessionInner,
"`self` and `base` must have been created, allocated, or retrieved from the same `Session`");
unsafe {
let mut velocity = sys::SpaceVelocity::out(ptr::null_mut());
let mut location = sys::SpaceLocation::out(&mut velocity as *mut _ as _);
let mut velocity = sys::SpaceVelocity::base_out(ptr::null_mut());
let mut location = sys::SpaceLocation::base_out(&mut velocity as *mut _ as _);
cvt((self.fp().locate_space)(
self.as_raw(),
base.as_raw(),
Expand Down
Loading