diff --git a/crates/bevy_openxr/src/init.rs b/crates/bevy_openxr/src/init.rs index d0d6f53..487783f 100644 --- a/crates/bevy_openxr/src/init.rs +++ b/crates/bevy_openxr/src/init.rs @@ -87,7 +87,7 @@ impl Plugin for XrInitPlugin { .run_if(status_equals(XrStatus::Ready)), end_xr_session .run_if(on_event::()) - .run_if(status_equals(XrStatus::Exiting)), + .run_if(status_equals(XrStatus::Stopping)), ) .in_set(XrPreUpdateSet::HandleEvents), ), @@ -188,8 +188,8 @@ impl XrInitPlugin { let instance = entry.create_instance( self.app_info.clone(), exts, - &["XR_APILAYER_LUNARG_api_dump"], - // &[], + // &["XR_APILAYER_LUNARG_api_dump"], + &[], backend, )?; let instance_props = instance.properties()?; @@ -317,7 +317,7 @@ fn init_xr_session( } .ok_or(XrError::NoAvailableFormat)?; - let mut swapchain = session.create_swapchain(SwapchainCreateInfo { + let swapchain = session.create_swapchain(SwapchainCreateInfo { create_flags: SwapchainCreateFlags::EMPTY, usage_flags: SwapchainUsageFlags::COLOR_ATTACHMENT | SwapchainUsageFlags::SAMPLED, format, @@ -404,6 +404,7 @@ pub fn create_xr_session( commands.insert_resource(graphics_info.clone()); commands.insert_resource(stage.clone()); commands.insert_resource(frame_stream.clone()); + commands.insert_resource(swapchain.clone()); commands.insert_resource(XrRenderResources { session, frame_stream, @@ -433,11 +434,15 @@ pub fn app_exit_xr( mut app_exiting: ResMut, mut app_exit_events: ResMut>, session_started: Res, + session: Option>, ) { // we need to temporarily intercept the exit event to allow the session to exit. app_exit_events.clear(); *app_exiting = AppExiting(true); session_started.set(false); + if let Some(session) = &session { + session.request_exit().expect("Failed to request exit"); + } } /// This system transfers important render resources from the main world to the render world when a session is created. diff --git a/crates/bevy_openxr/src/layer_builder.rs b/crates/bevy_openxr/src/layer_builder.rs index 08257bf..c2ff38e 100644 --- a/crates/bevy_openxr/src/layer_builder.rs +++ b/crates/bevy_openxr/src/layer_builder.rs @@ -33,7 +33,7 @@ impl<'a> SwapchainSubImage<'a> { pub fn swapchain(mut self, value: &'a XrSwapchain) -> Self { graphics_match!( &value.0; - swap => self.inner.swapchain = swap.as_raw() + swap => self.inner.swapchain = swap.lock().unwrap().as_raw() ); self.swapchain = Some(value); self diff --git a/crates/bevy_openxr/src/render.rs b/crates/bevy_openxr/src/render.rs index fc39edf..51d48d9 100644 --- a/crates/bevy_openxr/src/render.rs +++ b/crates/bevy_openxr/src/render.rs @@ -23,6 +23,7 @@ impl Plugin for XrRenderPlugin { PreUpdate, ( init_views.run_if(resource_added::), + insert_texture_views.run_if(session_started), wait_frame.run_if(session_started), ) .chain() @@ -38,13 +39,10 @@ impl Plugin for XrRenderPlugin { app.sub_app_mut(RenderApp).add_systems( Render, ( - ( - // begin_frame, - insert_texture_views - ) - .chain() - .in_set(RenderSet::PrepareAssets), - (locate_views, end_frame).chain().in_set(RenderSet::Cleanup), + // (insert_texture_views) + // .chain() + // .in_set(RenderSet::PrepareAssets), + (end_frame).chain().in_set(RenderSet::Cleanup), ) .run_if(session_started), ); @@ -255,7 +253,7 @@ fn calculate_projection(near_z: f32, fov: openxr::Fovf) -> Mat4 { pub fn insert_texture_views( swapchain_images: Res, - mut swapchain: ResMut, + swapchain: ResMut, mut manual_texture_views: ResMut, graphics_info: Res, ) { @@ -298,8 +296,8 @@ pub fn begin_frame(frame_stream: ResMut) { } pub fn end_frame( - mut frame_stream: ResMut, - mut swapchain: ResMut, + frame_stream: ResMut, + swapchain: ResMut, stage: Res, display_time: Res, graphics_info: Res, diff --git a/crates/bevy_openxr/src/resources.rs b/crates/bevy_openxr/src/resources.rs index 3c96fba..411e064 100644 --- a/crates/bevy_openxr/src/resources.rs +++ b/crates/bevy_openxr/src/resources.rs @@ -134,7 +134,7 @@ impl XrSession { pub fn create_swapchain(&self, info: SwapchainCreateInfo) -> Result { Ok(XrSwapchain(graphics_match!( &self.1; - session => session.create_swapchain(&info.try_into()?)? => XrSwapchain + session => Arc::new(Mutex::new(session.create_swapchain(&info.try_into()?)?)) => XrSwapchain ))) } } @@ -155,13 +155,13 @@ impl XrFrameStream { } pub fn end( - &mut self, + &self, display_time: openxr::Time, environment_blend_mode: openxr::EnvironmentBlendMode, layers: &[&dyn CompositionLayer], ) -> Result<()> { graphics_match!( - &mut self.0; + &self.0; stream => { let mut stream = stream.lock().unwrap(); let mut new_layers = vec![]; @@ -189,44 +189,45 @@ impl XrFrameStream { #[derive(Resource, Deref, DerefMut)] pub struct XrFrameWaiter(pub openxr::FrameWaiter); -#[derive(Resource)] +#[derive(Resource, Clone)] pub struct XrSwapchain(pub(crate) GraphicsWrap); impl GraphicsType for XrSwapchain { - type Inner = openxr::Swapchain; + type Inner = Arc>>; } impl XrSwapchain { - pub fn acquire_image(&mut self) -> Result { + pub fn acquire_image(&self) -> Result { graphics_match!( - &mut self.0; - swap => Ok(swap.acquire_image()?) + &self.0; + swap => Ok(swap.lock().unwrap().acquire_image()?) ) } - pub fn wait_image(&mut self, timeout: openxr::Duration) -> Result<()> { + pub fn wait_image(&self, timeout: openxr::Duration) -> Result<()> { graphics_match!( - &mut self.0; - swap => Ok(swap.wait_image(timeout)?) + &self.0; + swap => Ok(swap.lock().unwrap().wait_image(timeout)?) ) } - pub fn release_image(&mut self) -> Result<()> { + pub fn release_image(&self) -> Result<()> { graphics_match!( - &mut self.0; - swap => Ok(swap.release_image()?) + &self.0; + swap => Ok(swap.lock().unwrap().release_image()?) ) } pub fn enumerate_images( - &mut self, + &self, device: &wgpu::Device, format: wgpu::TextureFormat, resolution: UVec2, ) -> Result { graphics_match!( - &mut self.0; + &self.0; swap => { + let swap = swap.lock().unwrap(); let mut images = vec![]; for image in swap.enumerate_images()? { unsafe {