diff --git a/generator/src/main.rs b/generator/src/main.rs index 8d97a68..447b215 100644 --- a/generator/src/main.rs +++ b/generator/src/main.rs @@ -1539,12 +1539,7 @@ impl Parser { .filter(|name| polymorphic_whitelist.contains(&name[..])) .cloned() .collect::>(); - Some(self.generate_polymorphic_builders( - &struct_meta, - &simple_structs, - name, - &children, - )) + Some(self.generate_enum(&struct_meta, &simple_structs, name, &children)) } else { None } @@ -1561,7 +1556,7 @@ impl Parser { .collect::>(); let builders = self.structs.iter().filter_map(|(name, s)| { if whitelist.contains(&name[..]) { - Some(self.generate_builder(&struct_meta, &simple_structs, name, s)) + Some(self.generate_struct(&struct_meta, &simple_structs, name, s)) } else { None } @@ -1724,7 +1719,7 @@ impl Parser { out } - fn generate_polymorphic_builders( + fn generate_enum( &self, meta: &HashMap<&str, StructMeta>, simple: &IndexSet<&str>, @@ -1733,105 +1728,88 @@ impl Parser { ) -> TokenStream { let sys_ident = xr_ty_name(base_name); let base_ident = base_header_ty(base_name); + let raw_ident = Ident::new(&(base_ident.to_string() + "Raw"), Span::call_site()); let mut base_meta = StructMeta::default(); for name in children { base_meta |= *meta.get(&name[..]).unwrap(); } - let (type_params, type_args, marker, marker_init) = base_meta.type_params(); - let builders = children.iter().map(|name| { + let (type_params, type_args) = base_meta.type_params(); + + let mut variants = Vec::new(); + let mut as_raw = Vec::new(); + let mut raw_variants = Vec::new(); + + for name in children { let ident = xr_ty_name(name); + let variant_ident = variant_ident(name, base_name); + let s = self.structs.get(name).unwrap(); let conds = conditions(name, s.extension.as_ref().map(|x| &x[..])); - let inits = self.generate_builder_inits(s); - let setters = self.generate_setters(meta, simple, s); - quote! { + let inits = self.generate_inits(s); + + let (fields_ident, fields_defs, fields_as_raw) = + self.generate_member_data(meta, simple, s); + + variants.push(quote! { #conds - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct #ident #type_params { - inner: sys::#ident, - #marker + #variant_ident { + #(#fields_defs),* } - #conds - impl #type_params #ident #type_args { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::#ident { - #inits - ..unsafe { mem::zeroed() } - }, - #marker_init - } - } + }); - /// Initialize with the supplied raw values - /// - /// # Safety - /// - /// The guarantees normally enforced by this builder (e.g. lifetimes) must be - /// preserved. - #[inline] - pub unsafe fn from_raw(inner: sys::#ident) -> Self { - Self { - inner, - #marker_init - } - } + let snake_case_variant_ident = Ident::new( + &variant_ident.to_string().to_snake_case(), + Span::call_site(), + ); - #[inline] - pub fn into_raw(self) -> sys::#ident { - self.inner + let inits = inits.chain(fields_as_raw); + as_raw.push(quote! { + #base_ident::#variant_ident { + #(#fields_ident),* + } => #raw_ident { + #snake_case_variant_ident: sys::#ident { + #(#inits),* } + } + }); - #[inline] - pub fn as_raw(&self) -> &sys::#ident { - &self.inner - } + raw_variants.push(quote! { #snake_case_variant_ident: sys::#ident }); + } - #setters - } - #conds - impl #type_params Deref for #ident #type_args { - type Target = #base_ident #type_args; + quote! { + #[non_exhaustive] + pub enum #base_ident #type_params { + #(#variants),* + } - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - #conds - impl #type_params Default for #ident #type_args { - fn default() -> Self { - Self::new() + impl #type_params #base_ident #type_args { + pub(crate) fn as_raw(&self) -> #raw_ident { + match self { + #(#as_raw),* } } } - }); - quote! { - #[repr(transparent)] - pub struct #base_ident #type_params { - inner: sys::#sys_ident, - #marker + #[repr(C)] + pub(crate) union #raw_ident { + #(#raw_variants),* } - impl #type_params #base_ident #type_args { - #[inline] - pub(crate) fn as_raw(&self) -> &sys::#sys_ident { - &self.inner + + impl #raw_ident { + pub(crate) fn as_base(&self) -> *const sys::#sys_ident { + &self as *const _ as _ } } - #(#builders)* } } - fn generate_setters( + fn generate_member_data( &self, meta: &HashMap<&str, StructMeta>, simple: &IndexSet<&str>, s: &Struct, - ) -> TokenStream { + ) -> (Vec, Vec, Vec) { let lens = s .members .iter() @@ -1839,13 +1817,18 @@ impl Parser { .flat_map(|x| x.iter().filter(|&x| x != "null-terminated")) .map(|x| &x[..]) .collect::>(); - let setters = s.members.iter().filter_map(|m| { + + let mut fields_ident = Vec::new(); + let mut fields_defs = Vec::new(); + let mut fields_as_raw = Vec::new(); + + for m in &s.members { if m.name == "type" || m.name == "next" || lens.contains(&m.name[..]) { - return None; + continue; } let ident = xr_var_name(&m.name); let type_args = if let Some(meta) = meta.get(&m.ty[..]) { - let (_, type_args, _, _) = meta.type_params(); + let (_, type_args) = meta.type_params(); type_args } else if m.ty == "XrSwapchain" || m.ty == "XrSession" { quote! { } @@ -1854,38 +1837,32 @@ impl Parser { } else { quote! {} }; - let (ty, init) = match &m.ty[..] { - "XrResult" => ( - quote! { sys::Result }, - quote! { self.inner.#ident = value; }, - ), - "XrBool32" => ( - quote! { bool }, - quote! { self.inner.#ident = value.into(); }, - ), + let (field_def, as_raw) = match &m.ty[..] { + "XrResult" => (quote! { #ident: sys::Result }, quote! { #ident }), + "XrBool32" => (quote! { #ident: bool }, quote! { #ident: (*#ident).into() }), x if self.handles.contains(x) => { assert!(m.len.is_none()); let ty = xr_var_ty(self.api_aliases.as_ref(), m); ( - quote! { &'a #ty #type_args }, - quote! { self.inner.#ident = value.as_raw(); }, + quote! { #ident: &'a #ty #type_args }, + quote! { #ident: #ident.as_raw() }, ) } x if self.base_headers.contains_key(x) => { let ty = base_header_ty(x); ( - quote! { &'a #ty #type_args }, - quote! { self.inner.#ident = value as *const _ as _; }, + quote! { #ident: &'a #ty #type_args }, + quote! { #ident: #ident.as_raw().as_base() }, ) } _ => { if m.static_array_len.is_some() { if m.ty != "char" { - return None; + continue; } ( - quote! { &str }, - quote! { place_cstr(&mut self.inner.#ident, value); }, + quote! { #ident: &'a str }, + quote! { #ident: str_into_array(#ident) }, ) } else if let Some(ref len) = m.len { let mut inner = m.clone(); @@ -1894,11 +1871,8 @@ impl Parser { let ty = xr_var_ty(self.api_aliases.as_ref(), &inner); let len = xr_var_name(&len[0]); ( - quote! { &'a [#ty #type_args] }, - quote! { - self.inner.#ident = value.as_ptr() as *const _ as _; - self.inner.#len = value.len() as u32; - }, + quote! { #ident: &'a [#ty #type_args] }, + quote! { #len: #ident.len() as _, #ident: #ident.as_ptr() as _ }, ) } else if m.ptr_depth != 0 { let mut inner = m.clone(); @@ -1906,126 +1880,85 @@ impl Parser { let ty = xr_var_ty(self.api_aliases.as_ref(), &inner); if m.is_const { ( - quote! { &'a #ty #type_args }, - quote! { self.inner.#ident = value as *const _ as _; }, + quote! { #ident: &'a #ty #type_args }, + quote! { #ident: *#ident }, ) } else { ( - quote! { &'a mut #ty #type_args }, - quote! { self.inner.#ident = value as *mut _ as _; }, + quote! { #ident: &'a mut #ty #type_args }, + // TODO not sound + // https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=630c7d6aaac22feb47abba7913ad5ed9 + // is this still invalid when passed through FFI? -> probably yes + // quote! { #ident: *#ident as *const _ as *mut _ }, + quote! { #ident: std::ptr::null_mut() }, ) } } else if self.structs.contains_key(&m.ty) && !simple.contains(&m.ty[..]) { let ty = xr_var_ty(self.api_aliases.as_ref(), m); ( - quote! { #ty #type_args }, - quote! { self.inner.#ident = value.inner; }, + quote! { #ident: #ty #type_args }, + quote! { #ident: #ident.as_raw() }, ) } else { + let ty = xr_var_ty(self.api_aliases.as_ref(), m); ( - xr_var_ty(self.api_aliases.as_ref(), m), - quote! { self.inner.#ident = value; }, + quote! { #ident: #ty #type_args }, + quote! { #ident: *#ident }, ) } } }; - - let fn_type_params = match &m.ty[..] { - "XrAction" => quote! { }, - _ => quote! {}, - }; - Some(quote! { - #[inline] - pub fn #ident#fn_type_params(mut self, value: #ty) -> Self { - #init - self - } - }) - }); - quote! { - #(#setters)* + fields_ident.push(ident); + fields_defs.push(field_def); + fields_as_raw.push(as_raw); } + + (fields_ident, fields_defs, fields_as_raw) } - fn generate_builder_inits(&self, s: &Struct) -> TokenStream { - let inits = s.members.iter().filter_map(|m| { + fn generate_inits<'a>(&self, s: &'a Struct) -> impl Iterator + 'a { + s.members.iter().filter_map(move |m| { let ident = xr_var_name(&m.name); if m.name == "type" { let tag = xr_enum_value_name("XrStructureType", s.ty.as_ref().unwrap()); return Some(quote! { #ident: sys::StructureType::#tag }); } + if m.name == "next" { + return Some(quote! { #ident: std::ptr::null_mut() }); + } None - }); - quote! { - #(#inits,)* - } + }) } - fn generate_builder( + fn generate_struct( &self, meta: &HashMap<&str, StructMeta>, simple: &IndexSet<&str>, name: &str, s: &Struct, ) -> TokenStream { - let setters = self.generate_setters(meta, simple, s); + let (fields_ident, fields_defs, fields_as_raw) = self.generate_member_data(meta, simple, s); let ident = xr_ty_name(name); - let (type_params, type_args, marker, marker_init) = meta.get(name).unwrap().type_params(); - let inits = self.generate_builder_inits(s); + let (type_params, type_args) = meta.get(name).unwrap().type_params(); + let inits = self.generate_inits(s).chain(fields_as_raw); let conds = conditions(name, s.extension.as_ref().map(|x| &x[..])); let conds2 = conds.clone(); quote! { #[derive(Copy, Clone)] - #[repr(transparent)] #conds pub struct #ident #type_params { - inner: sys::#ident, - #marker + #(pub #fields_defs),* } + #conds2 impl #type_params #ident #type_args { #[inline] - pub fn new() -> Self { - Self { - inner: sys::#ident { - #inits - ..unsafe { mem::zeroed() } - }, - #marker_init + pub fn as_raw(&self) -> sys::#ident { + let Self { #(#fields_ident),* } = self; + sys::#ident { + #(#inits),* } } - - /// Initialize with the supplied raw values - /// - /// # Safety - /// - /// The guarantees normally enforced by this builder (e.g. lifetimes) must be - /// preserved. - #[inline] - pub unsafe fn from_raw(inner: sys::#ident) -> Self { - Self { - inner, - #marker_init - } - } - - #[inline] - pub fn into_raw(self) -> sys::#ident { - self.inner - } - - #[inline] - pub fn as_raw(&self) -> &sys::#ident { - &self.inner - } - - #setters - } - - impl #type_params Default for #ident #type_args { - fn default() -> Self { - Self::new() - } } } } @@ -2128,10 +2061,10 @@ struct StructMeta { } impl StructMeta { - fn type_params(self) -> (TokenStream, TokenStream, TokenStream, TokenStream) { + fn type_params(self) -> (TokenStream, TokenStream) { let mut params = Vec::new(); let mut args = Vec::new(); - if self.has_pointer { + if self.has_pointer || self.has_array { params.push(quote! { 'a }); args.push(quote! { 'a }); } @@ -2139,24 +2072,10 @@ impl StructMeta { params.push(quote! { G: Graphics }); args.push(quote! { G }); } - let phantom = if self.has_pointer && self.has_graphics { - quote! { &'a G } - } else if self.has_pointer { - quote! { &'a () } - } else if self.has_graphics { - quote! { G } - } else { - quote! {} - }; if params.is_empty() { - (quote! {}, quote! {}, quote! {}, quote! {}) + (quote! {}, quote! {}) } else { - ( - quote! { <#(#params),*> }, - quote! { <#(#args),*> }, - quote! { _marker: PhantomData<#phantom> }, - quote! { _marker: PhantomData }, - ) + (quote! { <#(#params),*> }, quote! { <#(#args),*> }) } } } @@ -2419,10 +2338,23 @@ fn tidy_comment(s: &str) -> Option { } fn base_header_ty(base_name: &str) -> Ident { + if base_name == "XrHapticBaseHeader" { + // `Haptic` clashes with the struct for the action type + return Ident::new("HapticData", Span::call_site()); + } + let base_header_pos = base_name.find("BaseHeader").unwrap(); assert!(base_name.starts_with("Xr")); - Ident::new( - &base_name[2..base_header_pos + "Base".len()], - Span::call_site(), - ) + Ident::new(&base_name[2..base_header_pos], Span::call_site()) +} + +fn variant_ident(struct_name: &str, base_name: &str) -> Ident { + let base_header_pos = base_name.find("BaseHeader").unwrap(); + assert!(base_name.starts_with("Xr")); + if base_name[..base_header_pos] == struct_name[..base_header_pos] { + Ident::new(&struct_name[base_header_pos..], Span::call_site()) + } else { + assert!(struct_name.starts_with("Xr")); + Ident::new(&struct_name[2..], Span::call_site()) + } } diff --git a/openxr/examples/vulkan.rs b/openxr/examples/vulkan.rs index e01c13b..f89ffce 100644 --- a/openxr/examples/vulkan.rs +++ b/openxr/examples/vulkan.rs @@ -710,28 +710,30 @@ pub fn main() { .end( xr_frame_state.predicted_display_time, environment_blend_mode, - &[ - &xr::CompositionLayerProjection::new().space(&stage).views(&[ - xr::CompositionLayerProjectionView::new() - .pose(views[0].pose) - .fov(views[0].fov) - .sub_image( - xr::SwapchainSubImage::new() - .swapchain(&swapchain.handle) - .image_array_index(0) - .image_rect(rect), - ), - xr::CompositionLayerProjectionView::new() - .pose(views[1].pose) - .fov(views[1].fov) - .sub_image( - xr::SwapchainSubImage::new() - .swapchain(&swapchain.handle) - .image_array_index(1) - .image_rect(rect), - ), - ]), - ], + &[&xr::CompositionLayer::Projection { + layer_flags: Default::default(), + space: &stage, + views: &[ + xr::CompositionLayerProjectionView { + pose: views[0].pose, + fov: views[0].fov, + sub_image: xr::SwapchainSubImage { + swapchain: &swapchain.handle, + image_array_index: 0, + image_rect: rect, + }, + }, + xr::CompositionLayerProjectionView { + pose: views[1].pose, + fov: views[1].fov, + sub_image: xr::SwapchainSubImage { + swapchain: &swapchain.handle, + image_array_index: 1, + image_rect: rect, + }, + }, + ], + }], ) .unwrap(); frame = (frame + 1) % PIPELINE_DEPTH as usize; diff --git a/openxr/src/action.rs b/openxr/src/action.rs index 383b4f1..a743d44 100644 --- a/openxr/src/action.rs +++ b/openxr/src/action.rs @@ -126,9 +126,9 @@ impl Action { &self, session: &Session, subaction_path: Path, - event: &HapticBase, + data: HapticData, ) -> Result<()> { - self.assert_event_validity(event); + self.assert_event_validity(&data); let info = sys::HapticActionInfo { ty: sys::HapticActionInfo::TYPE, @@ -140,7 +140,8 @@ impl Action { cvt((self.fp().apply_haptic_feedback)( session.as_raw(), &info, - event as *const _ as _, + // TODO `samples_consumed` pointer is not set + data.as_raw().as_base(), ))?; } Ok(()) @@ -148,22 +149,17 @@ impl Action { /// Check the invariants of the passed haptic `event`. /// The lifetime guarantees the validity of the non-null pointers. - fn assert_event_validity(&self, event: &HapticBase) { - match event.as_raw().ty { - sys::HapticVibration::TYPE => { + fn assert_event_validity(&self, data: &HapticData) { + match data { + HapticData::Vibration { .. } => { // nothing to check } - sys::HapticPcmVibrationFB::TYPE => { - assert!(self.instance().exts().fb_haptic_pcm.is_some()); - let event = - unsafe { std::mem::transmute::<&HapticBase, &HapticPcmVibrationFB>(event) } - .as_raw(); - assert!(event.buffer_size > 0); - assert_ne!(event.buffer, ptr::null()); - assert_ne!(event.samples_consumed, ptr::null_mut()); - } - ty => { - panic!("unsupported haptic type: {:?}", ty) + HapticData::PcmVibrationFB { buffer, .. } => { + assert!( + self.instance().exts().fb_haptic_pcm.is_some(), + "XR_FB_haptic_pcm not loaded" + ); + assert!(!buffer.is_empty(), "PCM Vibration buffer can't be empty"); } } } diff --git a/openxr/src/action_set.rs b/openxr/src/action_set.rs index 2429287..4b4edba 100644 --- a/openxr/src/action_set.rs +++ b/openxr/src/action_set.rs @@ -46,16 +46,17 @@ impl ActionSet { localized_name: &str, subaction_paths: &[Path], ) -> Result> { - let info = builder::ActionCreateInfo::new() - .action_name(name) - .localized_action_name(localized_name) - .subaction_paths(subaction_paths) - .action_type(T::TYPE); + let info = builder::ActionCreateInfo { + action_name: name, + localized_action_name: localized_name, + subaction_paths, + action_type: T::TYPE, + }; unsafe { let mut out = sys::Action::NULL; cvt((self.fp().create_action)( self.as_raw(), - info.as_raw(), + &info.as_raw(), &mut out, ))?; Ok(Action::from_raw(self.clone(), out)) diff --git a/openxr/src/frame_stream.rs b/openxr/src/frame_stream.rs index 711de0b..67e33e0 100644 --- a/openxr/src/frame_stream.rs +++ b/openxr/src/frame_stream.rs @@ -46,34 +46,36 @@ use crate::*; /// .end( /// state.predicted_display_time, /// openxr::EnvironmentBlendMode::OPAQUE, -/// &[&openxr::CompositionLayerProjection::new() -/// .space(world_space) -/// .views(&[ -/// openxr::CompositionLayerProjectionView::new() -/// .pose(views[0].pose) -/// .fov(views[0].fov) -/// .sub_image( -/// openxr::SwapchainSubImage::new() -/// .swapchain(swapchain) -/// .image_array_index(0) -/// .image_rect(openxr::Rect2Di { -/// offset: openxr::Offset2Di { x: 0, y: 0 }, -/// extent: view_resolution[0], -/// }), -/// ), -/// openxr::CompositionLayerProjectionView::new() -/// .pose(views[1].pose) -/// .fov(views[1].fov) -/// .sub_image( -/// openxr::SwapchainSubImage::new() -/// .swapchain(swapchain) -/// .image_array_index(1) -/// .image_rect(openxr::Rect2Di { -/// offset: openxr::Offset2Di { x: 0, y: 0 }, -/// extent: view_resolution[1], -/// }), -/// ), -/// ])], +/// &[&openxr::CompositionLayer::Projection { +/// layer_flags: Default::default(), +/// space: world_space, +/// views: &[ +/// openxr::CompositionLayerProjectionView { +/// pose: views[0].pose, +/// fov: views[0].fov, +/// sub_image: openxr::SwapchainSubImage { +/// swapchain, +/// image_array_index: 0, +/// image_rect: openxr::Rect2Di { +/// offset: openxr::Offset2Di { x: 0, y: 0 }, +/// extent: view_resolution[0], +/// }, +/// }, +/// }, +/// openxr::CompositionLayerProjectionView { +/// pose: views[1].pose, +/// fov: views[1].fov, +/// sub_image: openxr::SwapchainSubImage { +/// swapchain, +/// image_array_index: 1, +/// image_rect: openxr::Rect2Di { +/// offset: openxr::Offset2Di { x: 0, y: 0 }, +/// extent: view_resolution[1], +/// }, +/// }, +/// }, +/// ], +/// }], /// ) /// .unwrap(); /// # } @@ -105,9 +107,14 @@ impl FrameStream { &mut self, display_time: Time, environment_blend_mode: EnvironmentBlendMode, - layers: &[&CompositionLayerBase<'_, G>], + layers: &[&CompositionLayer<'_, G>], ) -> Result<()> { - self.assert_layers_validity(layers); + let layers = layers + .iter() + .inspect(|layer| self.assert_layer_validity(layer)) + .map(|layer| layer.as_raw()) + .collect::>(); + assert!(layers.len() <= u32::MAX as usize); let info = sys::FrameEndInfo { ty: sys::FrameEndInfo::TYPE, next: ptr::null(), @@ -136,18 +143,29 @@ impl FrameStream { &mut self, display_time: Time, environment_blend_mode: EnvironmentBlendMode, - layers: &[&CompositionLayerBase<'_, G>], + layers: &[&CompositionLayer<'_, G>], secondary_info: SecondaryEndInfo<'_, '_, '_, G>, ) -> Result<()> { - self.assert_layers_validity(layers); - self.assert_layers_validity(secondary_info.layers); + let layers = layers + .iter() + .inspect(|layer| self.assert_layer_validity(layer)) + .map(|layer| layer.as_raw()) + .collect::>(); + assert!(layers.len() <= u32::MAX as usize); + let secondary_layers = secondary_info + .layers + .iter() + .inspect(|layer| self.assert_layer_validity(layer)) + .map(|layer| layer.as_raw()) + .collect::>(); + assert!(secondary_layers.len() <= u32::MAX as usize); let single_secondary_info = [sys::SecondaryViewConfigurationLayerInfoMSFT { ty: sys::SecondaryViewConfigurationLayerInfoMSFT::TYPE, next: ptr::null(), view_configuration_type: secondary_info.ty, environment_blend_mode: secondary_info.environment_blend_mode, - layer_count: secondary_info.layers.len() as u32, - layers: secondary_info.layers.as_ptr() as *const _, + layer_count: secondary_layers.len() as u32, + layers: secondary_layers.as_ptr() as *const _, }]; let secondary_info = sys::SecondaryViewConfigurationFrameEndInfoMSFT { ty: sys::SecondaryViewConfigurationFrameEndInfoMSFT::TYPE, @@ -175,113 +193,76 @@ impl FrameStream { self.session.instance().fp() } - /// Check the invariants of the passed `layers`. + /// Check the invariants of the passed `layer`. /// The lifetimes guarantee the validity of non-null handles. - fn assert_layers_validity(&self, layers: &[&CompositionLayerBase<'_, G>]) { - // TODO `space` and `swapchain` must be from the same session (only in the spec for cube) - assert!(layers.len() <= u32::MAX as usize); - for &layer in layers { - match layer.as_raw().ty { - sys::CompositionLayerProjection::TYPE => { - let layer = unsafe { - std::mem::transmute::< - &CompositionLayerBase, - &CompositionLayerProjection, - >(layer) - } - .as_raw(); - assert_ne!(layer.space, sys::Space::NULL); - assert!(layer.view_count > 0); - let views = unsafe { - std::slice::from_raw_parts(layer.views, layer.view_count as usize) - }; - for view in views { - assert_ne!(view.sub_image.swapchain, sys::Swapchain::NULL); - } - } - sys::CompositionLayerQuad::TYPE => { - let layer = unsafe { - std::mem::transmute::<&CompositionLayerBase, &CompositionLayerQuad>( - layer, - ) - } - .as_raw(); - assert_ne!(layer.space, sys::Space::NULL); - assert_ne!(layer.sub_image.swapchain, sys::Swapchain::NULL); - } - sys::CompositionLayerCylinderKHR::TYPE => { - assert!(self - .session - .instance() - .exts() - .khr_composition_layer_cylinder - .is_some()); - let layer = unsafe { - std::mem::transmute::< - &CompositionLayerBase, - &CompositionLayerCylinderKHR, - >(layer) - } - .as_raw(); - assert_ne!(layer.space, sys::Space::NULL); - assert_ne!(layer.sub_image.swapchain, sys::Swapchain::NULL); - } - sys::CompositionLayerCubeKHR::TYPE => { - assert!(self - .session - .instance() - .exts() - .khr_composition_layer_cube - .is_some()); - let layer = - unsafe { - std::mem::transmute::< - &CompositionLayerBase, - &CompositionLayerCubeKHR, - >(layer) - } - .as_raw(); - assert_ne!(layer.space, sys::Space::NULL); - assert_ne!(layer.swapchain, sys::Swapchain::NULL); - } - sys::CompositionLayerEquirectKHR::TYPE => { - assert!(self - .session - .instance() - .exts() - .khr_composition_layer_equirect - .is_some()); - let layer = unsafe { - std::mem::transmute::< - &CompositionLayerBase, - &CompositionLayerEquirectKHR, - >(layer) - } - .as_raw(); - assert_ne!(layer.space, sys::Space::NULL); - assert_ne!(layer.sub_image.swapchain, sys::Swapchain::NULL); - } - sys::CompositionLayerEquirect2KHR::TYPE => { - assert!(self - .session - .instance() - .exts() - .khr_composition_layer_equirect2 - .is_some()); - let layer = unsafe { - std::mem::transmute::< - &CompositionLayerBase, - &CompositionLayerEquirect2KHR, - >(layer) - } - .as_raw(); - assert_ne!(layer.space, sys::Space::NULL); - assert_ne!(layer.sub_image.swapchain, sys::Swapchain::NULL); - } - ty => { - panic!("unsupported layer type: {:?}", ty) + fn assert_layer_validity(&self, layer: &CompositionLayer<'_, G>) { + match layer { + CompositionLayer::Projection { space, views, .. } => { + assert!(!views.is_empty()); + assert_eq!(self.session.as_raw(), space.session_handle()); + for CompositionLayerProjectionView { sub_image, .. } in *views { + assert_eq!(self.session.as_raw(), sub_image.swapchain.session_handle()); } } + CompositionLayer::Quad { + space, sub_image, .. + } => { + assert_eq!(space.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.face_count(), 1); + } + CompositionLayer::CylinderKHR { + space, sub_image, .. + } => { + assert!(self + .session + .instance() + .exts() + .khr_composition_layer_cylinder + .is_some()); + assert_eq!(space.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.face_count(), 1); + } + CompositionLayer::CubeKHR { + space, swapchain, .. + } => { + assert!(self + .session + .instance() + .exts() + .khr_composition_layer_cube + .is_some()); + assert_eq!(space.session_handle(), self.session.as_raw()); + assert_eq!(swapchain.session_handle(), self.session.as_raw()); + assert_eq!(swapchain.face_count(), 6); + } + CompositionLayer::EquirectKHR { + space, sub_image, .. + } => { + assert!(self + .session + .instance() + .exts() + .khr_composition_layer_equirect + .is_some()); + assert_eq!(space.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.face_count(), 1); + } + CompositionLayer::Equirect2KHR { + space, sub_image, .. + } => { + assert!(self + .session + .instance() + .exts() + .khr_composition_layer_equirect2 + .is_some()); + assert_eq!(space.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.session_handle(), self.session.as_raw()); + assert_eq!(sub_image.swapchain.face_count(), 1); + } } } } diff --git a/openxr/src/generated.rs b/openxr/src/generated.rs index 3fded46..f3461c9 100644 --- a/openxr/src/generated.rs +++ b/openxr/src/generated.rs @@ -6489,911 +6489,354 @@ pub(crate) mod builder { use crate::*; use std::{marker::PhantomData, mem, ops::Deref}; #[derive(Copy, Clone)] - #[repr(transparent)] pub struct SwapchainSubImage<'a, G: Graphics> { - inner: sys::SwapchainSubImage, - _marker: PhantomData<&'a G>, + pub swapchain: &'a Swapchain, + pub image_rect: Rect2Di, + pub image_array_index: u32, } impl<'a, G: Graphics> SwapchainSubImage<'a, G> { #[inline] - pub fn new() -> Self { - Self { - inner: sys::SwapchainSubImage { - ..unsafe { mem::zeroed() } - }, - _marker: PhantomData, + pub fn as_raw(&self) -> sys::SwapchainSubImage { + let Self { + swapchain, + image_rect, + image_array_index, + } = self; + sys::SwapchainSubImage { + swapchain: swapchain.as_raw(), + image_rect: *image_rect, + image_array_index: *image_array_index, } } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::SwapchainSubImage) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::SwapchainSubImage { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::SwapchainSubImage { - &self.inner - } - #[inline] - pub fn swapchain(mut self, value: &'a Swapchain) -> Self { - self.inner.swapchain = value.as_raw(); - self - } - #[inline] - pub fn image_rect(mut self, value: Rect2Di) -> Self { - self.inner.image_rect = value; - self - } - #[inline] - pub fn image_array_index(mut self, value: u32) -> Self { - self.inner.image_array_index = value; - self - } - } - impl<'a, G: Graphics> Default for SwapchainSubImage<'a, G> { - fn default() -> Self { - Self::new() - } } #[derive(Copy, Clone)] - #[repr(transparent)] pub struct CompositionLayerProjectionView<'a, G: Graphics> { - inner: sys::CompositionLayerProjectionView, - _marker: PhantomData<&'a G>, + pub pose: Posef, + pub fov: Fovf, + pub sub_image: SwapchainSubImage<'a, G>, } impl<'a, G: Graphics> CompositionLayerProjectionView<'a, G> { #[inline] - pub fn new() -> Self { - Self { - inner: sys::CompositionLayerProjectionView { - ty: sys::StructureType::COMPOSITION_LAYER_PROJECTION_VIEW, - ..unsafe { mem::zeroed() } - }, - _marker: PhantomData, + pub fn as_raw(&self) -> sys::CompositionLayerProjectionView { + let Self { + pose, + fov, + sub_image, + } = self; + sys::CompositionLayerProjectionView { + ty: sys::StructureType::COMPOSITION_LAYER_PROJECTION_VIEW, + next: std::ptr::null_mut(), + pose: *pose, + fov: *fov, + sub_image: sub_image.as_raw(), } } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::CompositionLayerProjectionView) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::CompositionLayerProjectionView { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::CompositionLayerProjectionView { - &self.inner - } - #[inline] - pub fn pose(mut self, value: Posef) -> Self { - self.inner.pose = value; - self - } - #[inline] - pub fn fov(mut self, value: Fovf) -> Self { - self.inner.fov = value; - self - } - #[inline] - pub fn sub_image(mut self, value: SwapchainSubImage<'a, G>) -> Self { - self.inner.sub_image = value.inner; - self - } - } - impl<'a, G: Graphics> Default for CompositionLayerProjectionView<'a, G> { - fn default() -> Self { - Self::new() - } } #[derive(Copy, Clone)] - #[repr(transparent)] pub struct ActionSetCreateInfo<'a> { - inner: sys::ActionSetCreateInfo, - _marker: PhantomData<&'a ()>, + pub action_set_name: &'a str, + pub localized_action_set_name: &'a str, + pub priority: u32, } impl<'a> ActionSetCreateInfo<'a> { #[inline] - pub fn new() -> Self { - Self { - inner: sys::ActionSetCreateInfo { - ty: sys::StructureType::ACTION_SET_CREATE_INFO, - ..unsafe { mem::zeroed() } - }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::ActionSetCreateInfo) -> Self { - Self { - inner, - _marker: PhantomData, + pub fn as_raw(&self) -> sys::ActionSetCreateInfo { + let Self { + action_set_name, + localized_action_set_name, + priority, + } = self; + sys::ActionSetCreateInfo { + ty: sys::StructureType::ACTION_SET_CREATE_INFO, + next: std::ptr::null_mut(), + action_set_name: str_into_array(action_set_name), + localized_action_set_name: str_into_array(localized_action_set_name), + priority: *priority, } } - #[inline] - pub fn into_raw(self) -> sys::ActionSetCreateInfo { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::ActionSetCreateInfo { - &self.inner - } - #[inline] - pub fn action_set_name(mut self, value: &str) -> Self { - place_cstr(&mut self.inner.action_set_name, value); - self - } - #[inline] - pub fn localized_action_set_name(mut self, value: &str) -> Self { - place_cstr(&mut self.inner.localized_action_set_name, value); - self - } - #[inline] - pub fn priority(mut self, value: u32) -> Self { - self.inner.priority = value; - self - } - } - impl<'a> Default for ActionSetCreateInfo<'a> { - fn default() -> Self { - Self::new() - } } #[derive(Copy, Clone)] - #[repr(transparent)] pub struct ActionCreateInfo<'a> { - inner: sys::ActionCreateInfo, - _marker: PhantomData<&'a ()>, + pub action_name: &'a str, + pub action_type: ActionType, + pub subaction_paths: &'a [Path], + pub localized_action_name: &'a str, } impl<'a> ActionCreateInfo<'a> { #[inline] - pub fn new() -> Self { - Self { - inner: sys::ActionCreateInfo { - ty: sys::StructureType::ACTION_CREATE_INFO, - ..unsafe { mem::zeroed() } + pub fn as_raw(&self) -> sys::ActionCreateInfo { + let Self { + action_name, + action_type, + subaction_paths, + localized_action_name, + } = self; + sys::ActionCreateInfo { + ty: sys::StructureType::ACTION_CREATE_INFO, + next: std::ptr::null_mut(), + action_name: str_into_array(action_name), + action_type: *action_type, + count_subaction_paths: subaction_paths.len() as _, + subaction_paths: subaction_paths.as_ptr() as _, + localized_action_name: str_into_array(localized_action_name), + } + } + } + #[non_exhaustive] + pub enum CompositionLayer<'a, G: Graphics> { + Projection { + layer_flags: CompositionLayerFlags, + space: &'a Space, + views: &'a [CompositionLayerProjectionView<'a, G>], + }, + Quad { + layer_flags: CompositionLayerFlags, + space: &'a Space, + eye_visibility: EyeVisibility, + sub_image: SwapchainSubImage<'a, G>, + pose: Posef, + size: Extent2Df, + }, + CylinderKHR { + layer_flags: CompositionLayerFlags, + space: &'a Space, + eye_visibility: EyeVisibility, + sub_image: SwapchainSubImage<'a, G>, + pose: Posef, + radius: f32, + central_angle: f32, + aspect_ratio: f32, + }, + CubeKHR { + layer_flags: CompositionLayerFlags, + space: &'a Space, + eye_visibility: EyeVisibility, + swapchain: &'a Swapchain, + image_array_index: u32, + orientation: Quaternionf, + }, + EquirectKHR { + layer_flags: CompositionLayerFlags, + space: &'a Space, + eye_visibility: EyeVisibility, + sub_image: SwapchainSubImage<'a, G>, + pose: Posef, + radius: f32, + scale: Vector2f, + bias: Vector2f, + }, + Equirect2KHR { + layer_flags: CompositionLayerFlags, + space: &'a Space, + eye_visibility: EyeVisibility, + sub_image: SwapchainSubImage<'a, G>, + pose: Posef, + radius: f32, + central_horizontal_angle: f32, + upper_vertical_angle: f32, + lower_vertical_angle: f32, + }, + } + impl<'a, G: Graphics> CompositionLayer<'a, G> { + pub(crate) fn as_raw(&self) -> CompositionLayerRaw { + match self { + CompositionLayer::Projection { + layer_flags, + space, + views, + } => CompositionLayerRaw { + projection: sys::CompositionLayerProjection { + ty: sys::StructureType::COMPOSITION_LAYER_PROJECTION, + next: std::ptr::null_mut(), + layer_flags: *layer_flags, + space: space.as_raw(), + view_count: views.len() as _, + views: views.as_ptr() as _, + }, }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::ActionCreateInfo) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::ActionCreateInfo { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::ActionCreateInfo { - &self.inner - } - #[inline] - pub fn action_name(mut self, value: &str) -> Self { - place_cstr(&mut self.inner.action_name, value); - self - } - #[inline] - pub fn action_type(mut self, value: ActionType) -> Self { - self.inner.action_type = value; - self - } - #[inline] - pub fn subaction_paths(mut self, value: &'a [Path]) -> Self { - self.inner.subaction_paths = value.as_ptr() as *const _ as _; - self.inner.count_subaction_paths = value.len() as u32; - self - } - #[inline] - pub fn localized_action_name(mut self, value: &str) -> Self { - place_cstr(&mut self.inner.localized_action_name, value); - self - } - } - impl<'a> Default for ActionCreateInfo<'a> { - fn default() -> Self { - Self::new() - } - } - #[repr(transparent)] - pub struct CompositionLayerBase<'a, G: Graphics> { - inner: sys::CompositionLayerBaseHeader, - _marker: PhantomData<&'a G>, - } - impl<'a, G: Graphics> CompositionLayerBase<'a, G> { - #[inline] - pub(crate) fn as_raw(&self) -> &sys::CompositionLayerBaseHeader { - &self.inner - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct CompositionLayerProjection<'a, G: Graphics> { - inner: sys::CompositionLayerProjection, - _marker: PhantomData<&'a G>, - } - impl<'a, G: Graphics> CompositionLayerProjection<'a, G> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::CompositionLayerProjection { - ty: sys::StructureType::COMPOSITION_LAYER_PROJECTION, - ..unsafe { mem::zeroed() } + CompositionLayer::Quad { + layer_flags, + space, + eye_visibility, + sub_image, + pose, + size, + } => CompositionLayerRaw { + quad: sys::CompositionLayerQuad { + ty: sys::StructureType::COMPOSITION_LAYER_QUAD, + next: std::ptr::null_mut(), + layer_flags: *layer_flags, + space: space.as_raw(), + eye_visibility: *eye_visibility, + sub_image: sub_image.as_raw(), + pose: *pose, + size: *size, + }, }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::CompositionLayerProjection) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::CompositionLayerProjection { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::CompositionLayerProjection { - &self.inner - } - #[inline] - pub fn layer_flags(mut self, value: CompositionLayerFlags) -> Self { - self.inner.layer_flags = value; - self - } - #[inline] - pub fn space(mut self, value: &'a Space) -> Self { - self.inner.space = value.as_raw(); - self - } - #[inline] - pub fn views(mut self, value: &'a [CompositionLayerProjectionView<'a, G>]) -> Self { - self.inner.views = value.as_ptr() as *const _ as _; - self.inner.view_count = value.len() as u32; - self - } - } - impl<'a, G: Graphics> Deref for CompositionLayerProjection<'a, G> { - type Target = CompositionLayerBase<'a, G>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - impl<'a, G: Graphics> Default for CompositionLayerProjection<'a, G> { - fn default() -> Self { - Self::new() - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct CompositionLayerQuad<'a, G: Graphics> { - inner: sys::CompositionLayerQuad, - _marker: PhantomData<&'a G>, - } - impl<'a, G: Graphics> CompositionLayerQuad<'a, G> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::CompositionLayerQuad { - ty: sys::StructureType::COMPOSITION_LAYER_QUAD, - ..unsafe { mem::zeroed() } + CompositionLayer::CylinderKHR { + layer_flags, + space, + eye_visibility, + sub_image, + pose, + radius, + central_angle, + aspect_ratio, + } => CompositionLayerRaw { + cylinder_khr: sys::CompositionLayerCylinderKHR { + ty: sys::StructureType::COMPOSITION_LAYER_CYLINDER_KHR, + next: std::ptr::null_mut(), + layer_flags: *layer_flags, + space: space.as_raw(), + eye_visibility: *eye_visibility, + sub_image: sub_image.as_raw(), + pose: *pose, + radius: *radius, + central_angle: *central_angle, + aspect_ratio: *aspect_ratio, + }, }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::CompositionLayerQuad) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::CompositionLayerQuad { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::CompositionLayerQuad { - &self.inner - } - #[inline] - pub fn layer_flags(mut self, value: CompositionLayerFlags) -> Self { - self.inner.layer_flags = value; - self - } - #[inline] - pub fn space(mut self, value: &'a Space) -> Self { - self.inner.space = value.as_raw(); - self - } - #[inline] - pub fn eye_visibility(mut self, value: EyeVisibility) -> Self { - self.inner.eye_visibility = value; - self - } - #[inline] - pub fn sub_image(mut self, value: SwapchainSubImage<'a, G>) -> Self { - self.inner.sub_image = value.inner; - self - } - #[inline] - pub fn pose(mut self, value: Posef) -> Self { - self.inner.pose = value; - self - } - #[inline] - pub fn size(mut self, value: Extent2Df) -> Self { - self.inner.size = value; - self - } - } - impl<'a, G: Graphics> Deref for CompositionLayerQuad<'a, G> { - type Target = CompositionLayerBase<'a, G>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - impl<'a, G: Graphics> Default for CompositionLayerQuad<'a, G> { - fn default() -> Self { - Self::new() - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct CompositionLayerCylinderKHR<'a, G: Graphics> { - inner: sys::CompositionLayerCylinderKHR, - _marker: PhantomData<&'a G>, - } - impl<'a, G: Graphics> CompositionLayerCylinderKHR<'a, G> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::CompositionLayerCylinderKHR { - ty: sys::StructureType::COMPOSITION_LAYER_CYLINDER_KHR, - ..unsafe { mem::zeroed() } - }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::CompositionLayerCylinderKHR) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::CompositionLayerCylinderKHR { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::CompositionLayerCylinderKHR { - &self.inner - } - #[inline] - pub fn layer_flags(mut self, value: CompositionLayerFlags) -> Self { - self.inner.layer_flags = value; - self - } - #[inline] - pub fn space(mut self, value: &'a Space) -> Self { - self.inner.space = value.as_raw(); - self - } - #[inline] - pub fn eye_visibility(mut self, value: EyeVisibility) -> Self { - self.inner.eye_visibility = value; - self - } - #[inline] - pub fn sub_image(mut self, value: SwapchainSubImage<'a, G>) -> Self { - self.inner.sub_image = value.inner; - self - } - #[inline] - pub fn pose(mut self, value: Posef) -> Self { - self.inner.pose = value; - self - } - #[inline] - pub fn radius(mut self, value: f32) -> Self { - self.inner.radius = value; - self - } - #[inline] - pub fn central_angle(mut self, value: f32) -> Self { - self.inner.central_angle = value; - self - } - #[inline] - pub fn aspect_ratio(mut self, value: f32) -> Self { - self.inner.aspect_ratio = value; - self - } - } - impl<'a, G: Graphics> Deref for CompositionLayerCylinderKHR<'a, G> { - type Target = CompositionLayerBase<'a, G>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - impl<'a, G: Graphics> Default for CompositionLayerCylinderKHR<'a, G> { - fn default() -> Self { - Self::new() - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct CompositionLayerCubeKHR<'a, G: Graphics> { - inner: sys::CompositionLayerCubeKHR, - _marker: PhantomData<&'a G>, - } - impl<'a, G: Graphics> CompositionLayerCubeKHR<'a, G> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::CompositionLayerCubeKHR { - ty: sys::StructureType::COMPOSITION_LAYER_CUBE_KHR, - ..unsafe { mem::zeroed() } + CompositionLayer::CubeKHR { + layer_flags, + space, + eye_visibility, + swapchain, + image_array_index, + orientation, + } => CompositionLayerRaw { + cube_khr: sys::CompositionLayerCubeKHR { + ty: sys::StructureType::COMPOSITION_LAYER_CUBE_KHR, + next: std::ptr::null_mut(), + layer_flags: *layer_flags, + space: space.as_raw(), + eye_visibility: *eye_visibility, + swapchain: swapchain.as_raw(), + image_array_index: *image_array_index, + orientation: *orientation, + }, }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::CompositionLayerCubeKHR) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::CompositionLayerCubeKHR { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::CompositionLayerCubeKHR { - &self.inner - } - #[inline] - pub fn layer_flags(mut self, value: CompositionLayerFlags) -> Self { - self.inner.layer_flags = value; - self - } - #[inline] - pub fn space(mut self, value: &'a Space) -> Self { - self.inner.space = value.as_raw(); - self - } - #[inline] - pub fn eye_visibility(mut self, value: EyeVisibility) -> Self { - self.inner.eye_visibility = value; - self - } - #[inline] - pub fn swapchain(mut self, value: &'a Swapchain) -> Self { - self.inner.swapchain = value.as_raw(); - self - } - #[inline] - pub fn image_array_index(mut self, value: u32) -> Self { - self.inner.image_array_index = value; - self - } - #[inline] - pub fn orientation(mut self, value: Quaternionf) -> Self { - self.inner.orientation = value; - self - } - } - impl<'a, G: Graphics> Deref for CompositionLayerCubeKHR<'a, G> { - type Target = CompositionLayerBase<'a, G>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - impl<'a, G: Graphics> Default for CompositionLayerCubeKHR<'a, G> { - fn default() -> Self { - Self::new() - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct CompositionLayerEquirectKHR<'a, G: Graphics> { - inner: sys::CompositionLayerEquirectKHR, - _marker: PhantomData<&'a G>, - } - impl<'a, G: Graphics> CompositionLayerEquirectKHR<'a, G> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::CompositionLayerEquirectKHR { - ty: sys::StructureType::COMPOSITION_LAYER_EQUIRECT_KHR, - ..unsafe { mem::zeroed() } + CompositionLayer::EquirectKHR { + layer_flags, + space, + eye_visibility, + sub_image, + pose, + radius, + scale, + bias, + } => CompositionLayerRaw { + equirect_khr: sys::CompositionLayerEquirectKHR { + ty: sys::StructureType::COMPOSITION_LAYER_EQUIRECT_KHR, + next: std::ptr::null_mut(), + layer_flags: *layer_flags, + space: space.as_raw(), + eye_visibility: *eye_visibility, + sub_image: sub_image.as_raw(), + pose: *pose, + radius: *radius, + scale: *scale, + bias: *bias, + }, }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::CompositionLayerEquirectKHR) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::CompositionLayerEquirectKHR { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::CompositionLayerEquirectKHR { - &self.inner - } - #[inline] - pub fn layer_flags(mut self, value: CompositionLayerFlags) -> Self { - self.inner.layer_flags = value; - self - } - #[inline] - pub fn space(mut self, value: &'a Space) -> Self { - self.inner.space = value.as_raw(); - self - } - #[inline] - pub fn eye_visibility(mut self, value: EyeVisibility) -> Self { - self.inner.eye_visibility = value; - self - } - #[inline] - pub fn sub_image(mut self, value: SwapchainSubImage<'a, G>) -> Self { - self.inner.sub_image = value.inner; - self - } - #[inline] - pub fn pose(mut self, value: Posef) -> Self { - self.inner.pose = value; - self - } - #[inline] - pub fn radius(mut self, value: f32) -> Self { - self.inner.radius = value; - self - } - #[inline] - pub fn scale(mut self, value: Vector2f) -> Self { - self.inner.scale = value; - self - } - #[inline] - pub fn bias(mut self, value: Vector2f) -> Self { - self.inner.bias = value; - self - } - } - impl<'a, G: Graphics> Deref for CompositionLayerEquirectKHR<'a, G> { - type Target = CompositionLayerBase<'a, G>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - impl<'a, G: Graphics> Default for CompositionLayerEquirectKHR<'a, G> { - fn default() -> Self { - Self::new() - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct CompositionLayerEquirect2KHR<'a, G: Graphics> { - inner: sys::CompositionLayerEquirect2KHR, - _marker: PhantomData<&'a G>, - } - impl<'a, G: Graphics> CompositionLayerEquirect2KHR<'a, G> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::CompositionLayerEquirect2KHR { - ty: sys::StructureType::COMPOSITION_LAYER_EQUIRECT2_KHR, - ..unsafe { mem::zeroed() } + CompositionLayer::Equirect2KHR { + layer_flags, + space, + eye_visibility, + sub_image, + pose, + radius, + central_horizontal_angle, + upper_vertical_angle, + lower_vertical_angle, + } => CompositionLayerRaw { + equirect2_khr: sys::CompositionLayerEquirect2KHR { + ty: sys::StructureType::COMPOSITION_LAYER_EQUIRECT2_KHR, + next: std::ptr::null_mut(), + layer_flags: *layer_flags, + space: space.as_raw(), + eye_visibility: *eye_visibility, + sub_image: sub_image.as_raw(), + pose: *pose, + radius: *radius, + central_horizontal_angle: *central_horizontal_angle, + upper_vertical_angle: *upper_vertical_angle, + lower_vertical_angle: *lower_vertical_angle, + }, }, - _marker: PhantomData, } } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::CompositionLayerEquirect2KHR) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::CompositionLayerEquirect2KHR { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::CompositionLayerEquirect2KHR { - &self.inner - } - #[inline] - pub fn layer_flags(mut self, value: CompositionLayerFlags) -> Self { - self.inner.layer_flags = value; - self - } - #[inline] - pub fn space(mut self, value: &'a Space) -> Self { - self.inner.space = value.as_raw(); - self - } - #[inline] - pub fn eye_visibility(mut self, value: EyeVisibility) -> Self { - self.inner.eye_visibility = value; - self - } - #[inline] - pub fn sub_image(mut self, value: SwapchainSubImage<'a, G>) -> Self { - self.inner.sub_image = value.inner; - self - } - #[inline] - pub fn pose(mut self, value: Posef) -> Self { - self.inner.pose = value; - self - } - #[inline] - pub fn radius(mut self, value: f32) -> Self { - self.inner.radius = value; - self - } - #[inline] - pub fn central_horizontal_angle(mut self, value: f32) -> Self { - self.inner.central_horizontal_angle = value; - self - } - #[inline] - pub fn upper_vertical_angle(mut self, value: f32) -> Self { - self.inner.upper_vertical_angle = value; - self - } - #[inline] - pub fn lower_vertical_angle(mut self, value: f32) -> Self { - self.inner.lower_vertical_angle = value; - self - } } - impl<'a, G: Graphics> Deref for CompositionLayerEquirect2KHR<'a, G> { - type Target = CompositionLayerBase<'a, G>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - impl<'a, G: Graphics> Default for CompositionLayerEquirect2KHR<'a, G> { - fn default() -> Self { - Self::new() - } - } - #[repr(transparent)] - pub struct HapticBase<'a> { - inner: sys::HapticBaseHeader, - _marker: PhantomData<&'a ()>, - } - impl<'a> HapticBase<'a> { - #[inline] - pub(crate) fn as_raw(&self) -> &sys::HapticBaseHeader { - &self.inner - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct HapticVibration<'a> { - inner: sys::HapticVibration, - _marker: PhantomData<&'a ()>, - } - impl<'a> HapticVibration<'a> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::HapticVibration { - ty: sys::StructureType::HAPTIC_VIBRATION, - ..unsafe { mem::zeroed() } + #[repr(C)] + pub(crate) union CompositionLayerRaw { + projection: sys::CompositionLayerProjection, + quad: sys::CompositionLayerQuad, + cylinder_khr: sys::CompositionLayerCylinderKHR, + cube_khr: sys::CompositionLayerCubeKHR, + equirect_khr: sys::CompositionLayerEquirectKHR, + equirect2_khr: sys::CompositionLayerEquirect2KHR, + } + impl CompositionLayerRaw { + pub(crate) fn as_base(&self) -> *const sys::CompositionLayerBaseHeader { + &self as *const _ as _ + } + } + #[non_exhaustive] + pub enum HapticData<'a> { + Vibration { + duration: Duration, + frequency: f32, + amplitude: f32, + }, + PcmVibrationFB { + buffer: &'a [f32], + sample_rate: f32, + append: bool, + samples_consumed: &'a mut u32, + }, + } + impl<'a> HapticData<'a> { + pub(crate) fn as_raw(&self) -> HapticDataRaw { + match self { + HapticData::Vibration { + duration, + frequency, + amplitude, + } => HapticDataRaw { + vibration: sys::HapticVibration { + ty: sys::StructureType::HAPTIC_VIBRATION, + next: std::ptr::null_mut(), + duration: *duration, + frequency: *frequency, + amplitude: *amplitude, + }, }, - _marker: PhantomData, - } - } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::HapticVibration) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::HapticVibration { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::HapticVibration { - &self.inner - } - #[inline] - pub fn duration(mut self, value: Duration) -> Self { - self.inner.duration = value; - self - } - #[inline] - pub fn frequency(mut self, value: f32) -> Self { - self.inner.frequency = value; - self - } - #[inline] - pub fn amplitude(mut self, value: f32) -> Self { - self.inner.amplitude = value; - self - } - } - impl<'a> Deref for HapticVibration<'a> { - type Target = HapticBase<'a>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } - } - impl<'a> Default for HapticVibration<'a> { - fn default() -> Self { - Self::new() - } - } - #[derive(Copy, Clone)] - #[repr(transparent)] - pub struct HapticPcmVibrationFB<'a> { - inner: sys::HapticPcmVibrationFB, - _marker: PhantomData<&'a ()>, - } - impl<'a> HapticPcmVibrationFB<'a> { - #[inline] - pub fn new() -> Self { - Self { - inner: sys::HapticPcmVibrationFB { - ty: sys::StructureType::HAPTIC_PCM_VIBRATION_FB, - ..unsafe { mem::zeroed() } + HapticData::PcmVibrationFB { + buffer, + sample_rate, + append, + samples_consumed, + } => HapticDataRaw { + pcm_vibration_fb: sys::HapticPcmVibrationFB { + ty: sys::StructureType::HAPTIC_PCM_VIBRATION_FB, + next: std::ptr::null_mut(), + buffer_size: buffer.len() as _, + buffer: buffer.as_ptr() as _, + sample_rate: *sample_rate, + append: (*append).into(), + samples_consumed: std::ptr::null_mut(), + }, }, - _marker: PhantomData, } } - #[doc = r" Initialize with the supplied raw values"] - #[doc = r""] - #[doc = r" # Safety"] - #[doc = r""] - #[doc = r" The guarantees normally enforced by this builder (e.g. lifetimes) must be"] - #[doc = r" preserved."] - #[inline] - pub unsafe fn from_raw(inner: sys::HapticPcmVibrationFB) -> Self { - Self { - inner, - _marker: PhantomData, - } - } - #[inline] - pub fn into_raw(self) -> sys::HapticPcmVibrationFB { - self.inner - } - #[inline] - pub fn as_raw(&self) -> &sys::HapticPcmVibrationFB { - &self.inner - } - #[inline] - pub fn buffer(mut self, value: &'a [f32]) -> Self { - self.inner.buffer = value.as_ptr() as *const _ as _; - self.inner.buffer_size = value.len() as u32; - self - } - #[inline] - pub fn sample_rate(mut self, value: f32) -> Self { - self.inner.sample_rate = value; - self - } - #[inline] - pub fn append(mut self, value: bool) -> Self { - self.inner.append = value.into(); - self - } - #[inline] - pub fn samples_consumed(mut self, value: &'a mut u32) -> Self { - self.inner.samples_consumed = value as *mut _ as _; - self - } } - impl<'a> Deref for HapticPcmVibrationFB<'a> { - type Target = HapticBase<'a>; - #[inline] - fn deref(&self) -> &Self::Target { - unsafe { mem::transmute(&self.inner) } - } + #[repr(C)] + pub(crate) union HapticDataRaw { + vibration: sys::HapticVibration, + pcm_vibration_fb: sys::HapticPcmVibrationFB, } - impl<'a> Default for HapticPcmVibrationFB<'a> { - fn default() -> Self { - Self::new() + impl HapticDataRaw { + pub(crate) fn as_base(&self) -> *const sys::HapticBaseHeader { + &self as *const _ as _ } } } diff --git a/openxr/src/instance.rs b/openxr/src/instance.rs index e5f3417..e649d39 100644 --- a/openxr/src/instance.rs +++ b/openxr/src/instance.rs @@ -616,15 +616,16 @@ impl Instance { localized_name: &str, priority: u32, ) -> Result { - let info = builder::ActionSetCreateInfo::new() - .action_set_name(name) - .localized_action_set_name(localized_name) - .priority(priority); + let info = builder::ActionSetCreateInfo { + action_set_name: name, + localized_action_set_name: localized_name, + priority, + }; unsafe { let mut out = sys::ActionSet::NULL; cvt((self.fp().create_action_set)( self.as_raw(), - info.as_raw(), + &info.as_raw(), &mut out, ))?; Ok(ActionSet::from_raw(self.clone(), out)) diff --git a/openxr/src/lib.rs b/openxr/src/lib.rs index c32ca52..eb299c3 100644 --- a/openxr/src/lib.rs +++ b/openxr/src/lib.rs @@ -44,10 +44,7 @@ mod localization_map_ml; pub use localization_map_ml::*; pub use builder::{ - CompositionLayerBase, CompositionLayerCubeKHR, CompositionLayerCylinderKHR, - CompositionLayerEquirect2KHR, CompositionLayerEquirectKHR, CompositionLayerProjection, - CompositionLayerProjectionView, CompositionLayerQuad, HapticBase, HapticPcmVibrationFB, - HapticVibration, SwapchainSubImage, + CompositionLayer, CompositionLayerProjectionView, HapticData, SwapchainSubImage, }; pub type Result = std::result::Result; @@ -82,6 +79,12 @@ fn place_cstr(out: &mut [c_char], s: &str) { out[s.len()] = 0; } +fn str_into_array(s: &str) -> [c_char; LENGTH] { + let mut out = [0; LENGTH]; + place_cstr(&mut out, s); + out +} + unsafe fn fixed_str(x: &[c_char]) -> &str { std::str::from_utf8_unchecked(std::ffi::CStr::from_ptr(x.as_ptr()).to_bytes()) } diff --git a/openxr/src/secondary_view.rs b/openxr/src/secondary_view.rs index 9c810f1..fb8c0d5 100644 --- a/openxr/src/secondary_view.rs +++ b/openxr/src/secondary_view.rs @@ -8,5 +8,5 @@ pub struct SecondaryViewState { pub struct SecondaryEndInfo<'a, 'b, 'c, G: Graphics> { pub ty: ViewConfigurationType, pub environment_blend_mode: EnvironmentBlendMode, - pub layers: &'a [&'b CompositionLayerBase<'c, G>], + pub layers: &'a [&'b CompositionLayer<'c, G>], } diff --git a/openxr/src/session.rs b/openxr/src/session.rs index 3775cec..a7a0bfc 100644 --- a/openxr/src/session.rs +++ b/openxr/src/session.rs @@ -487,6 +487,7 @@ impl Session { #[inline] pub fn create_swapchain(&self, info: &SwapchainCreateInfo) -> Result> { + assert!(info.face_count == 1 || info.face_count == 6); let mut out = sys::Swapchain::NULL; let info = sys::SwapchainCreateInfo { ty: sys::SwapchainCreateInfo::TYPE, @@ -503,7 +504,7 @@ impl Session { }; unsafe { cvt((self.fp().create_swapchain)(self.as_raw(), &info, &mut out))?; - Ok(Swapchain::from_raw(self.clone(), out)) + Ok(Swapchain::from_raw(self.clone(), out, info.face_count)) } } diff --git a/openxr/src/space.rs b/openxr/src/space.rs index 77c4add..d19c955 100644 --- a/openxr/src/space.rs +++ b/openxr/src/space.rs @@ -53,6 +53,11 @@ impl Space { &self.session.instance } + #[inline] + pub(crate) fn session_handle(&self) -> sys::Session { + self.session.handle + } + /// Set the debug name of this `Space`, if `XR_EXT_debug_utils` is loaded #[inline] pub fn set_name(&mut self, name: &str) -> Result<()> { diff --git a/openxr/src/swapchain.rs b/openxr/src/swapchain.rs index dfeb956..8c63ad5 100644 --- a/openxr/src/swapchain.rs +++ b/openxr/src/swapchain.rs @@ -9,6 +9,8 @@ pub struct Swapchain { _marker: PhantomData, /// Whether `wait_image` was called more recently than `release_image` waited: bool, + /// Required for validation when submitting layers + face_count: u32, } impl Swapchain { @@ -18,12 +20,13 @@ impl Swapchain { /// /// `handle` must be a valid swapchain handle associated with `session` and created with `flags`. #[inline] - pub unsafe fn from_raw(session: Session, handle: sys::Swapchain) -> Self { + pub unsafe fn from_raw(session: Session, handle: sys::Swapchain, face_count: u32) -> Self { Self { session, handle, _marker: PhantomData, waited: false, + face_count, } } @@ -39,6 +42,16 @@ impl Swapchain { self.session.instance() } + #[inline] + pub(crate) fn session_handle(&self) -> sys::Session { + self.session.as_raw() + } + + #[inline] + pub(crate) fn face_count(&self) -> u32 { + self.face_count + } + /// Set the debug name of this `Swapchain`, if `XR_EXT_debug_utils` is loaded #[inline] pub fn set_name(&mut self, name: &str) -> Result<()> {