From 9d6d60cbe73976e7ab08ea344167e7205e1711fc Mon Sep 17 00:00:00 2001 From: Schmarni Date: Thu, 25 Jan 2024 06:39:44 +0100 Subject: [PATCH] implement simple pipelined rendering --- src/lib.rs | 45 ++++++++++++++++++++++++++++++++++++--------- src/xr_init/mod.rs | 17 +++++++++++++---- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f5675b7..2659469 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,7 @@ use openxr as xr; use resources::*; use xr::{FormFactor, FrameState}; use xr_init::{ - xr_only, xr_render_only, CleanupXrData, XrEarlyInitPlugin, XrShouldRender, XrStatus, + xr_only, xr_render_only, CleanupXrData, XrEarlyInitPlugin, XrShouldRender, XrStatus, XrHasWaited, xr_after_wait_only, }; use xr_input::controllers::XrControllerType; use xr_input::hands::emulated::HandEmulationPlugin; @@ -118,7 +118,7 @@ impl Plugin for OpenXrPlugin { app.add_systems( PreUpdate, ( - xr_reset_should_render, + xr_reset_per_frame_resources, xr_wait_frame.run_if(xr_only()), locate_views.run_if(xr_only()), apply_deferred, @@ -130,15 +130,15 @@ impl Plugin for OpenXrPlugin { render_app.add_systems( Render, xr_begin_frame - .run_if(xr_only()) - .run_if(xr_render_only()) + .run_if(xr_only()).run_if(xr_after_wait_only()) + // .run_if(xr_render_only()) .after(RenderSet::ExtractCommands) .before(xr_pre_frame), ); render_app.add_systems( Render, xr_pre_frame - .run_if(xr_only()) + .run_if(xr_only()).run_if(xr_after_wait_only()) .run_if(xr_render_only()) // Do NOT touch this ordering! idk why but you can NOT just put in a RenderSet // right before rendering @@ -162,10 +162,34 @@ impl Plugin for OpenXrPlugin { render_app.add_systems( Render, xr_end_frame - .run_if(xr_only()) + .run_if(xr_only()).run_if(xr_after_wait_only()) .run_if(xr_render_only()) .after(RenderSet::Render), ); + render_app.add_systems( + Render, + xr_skip_frame + .run_if(xr_only()).run_if(xr_after_wait_only()) + .run_if(not(xr_render_only())) + .after(RenderSet::Render), + ); + } +} + +fn xr_skip_frame( + xr_swapchain: Res, + xr_frame_state: Res, + environment_blend_mode: Res, +) { + let swapchain: &Swapchain = &xr_swapchain; + // swapchain.begin().unwrap(); + match swapchain { + Swapchain::Vulkan(swap) => { + swap.stream + .lock() + .unwrap() + .end(xr_frame_state.predicted_display_time, **environment_blend_mode, &[]).unwrap(); + } } } @@ -180,8 +204,8 @@ impl PluginGroup for DefaultXrPlugins { fn build(self) -> PluginGroupBuilder { DefaultPlugins .build() + .disable::() .disable::() - // .disable::() .add_before::(OpenXrPlugin { prefered_blend_mode: self.prefered_blend_mode, reqeusted_extensions: self.reqeusted_extensions, @@ -211,8 +235,9 @@ impl PluginGroup for DefaultXrPlugins { } } -fn xr_reset_should_render(mut should: ResMut) { +fn xr_reset_per_frame_resources(mut should: ResMut,mut waited: ResMut) { **should = false; + **waited = false; } fn xr_poll_events( @@ -271,6 +296,7 @@ pub fn xr_wait_frame( mut frame_state: ResMut, mut frame_waiter: ResMut, mut should_render: ResMut, + mut waited: ResMut, ) { { let _span = info_span!("xr_wait_frame").entered(); @@ -286,11 +312,12 @@ pub fn xr_wait_frame( { frame_state.predicted_display_time = xr::Time::from_nanos( frame_state.predicted_display_time.as_nanos() - + (frame_state.predicted_display_period.as_nanos() * 1), + + (frame_state.predicted_display_period.as_nanos() * 0), ); }; info!("Post Frame Wait"); **should_render = frame_state.should_render; + **waited = true; } } diff --git a/src/xr_init/mod.rs b/src/xr_init/mod.rs index d7db1c9..06d9578 100644 --- a/src/xr_init/mod.rs +++ b/src/xr_init/mod.rs @@ -33,16 +33,23 @@ pub enum XrStatus { Resource, Clone, Copy, PartialEq, Eq, Reflect, Debug, ExtractResource, Default, Deref, DerefMut, )] pub struct XrShouldRender(bool); +#[derive( + Resource, Clone, Copy, PartialEq, Eq, Reflect, Debug, ExtractResource, Default, Deref, DerefMut, +)] +pub struct XrHasWaited(bool); pub struct XrEarlyInitPlugin; pub struct XrInitPlugin; -pub fn xr_only() -> impl FnMut(Option>) -> bool { - resource_exists_and_equals(XrStatus::Enabled) +pub fn xr_only() -> impl FnMut(Res) -> bool { + resource_equals(XrStatus::Enabled) } -pub fn xr_render_only() -> impl FnMut(Option>) -> bool { - resource_exists_and_equals(XrShouldRender(true)) +pub fn xr_render_only() -> impl FnMut(Res) -> bool { + resource_equals(XrShouldRender(true)) +} +pub fn xr_after_wait_only() -> impl FnMut(Res) -> bool { + resource_equals(XrHasWaited(true)) } impl Plugin for XrEarlyInitPlugin { @@ -59,7 +66,9 @@ impl Plugin for XrInitPlugin { add_schedules(app); app.add_plugins(ExtractResourcePlugin::::default()); app.add_plugins(ExtractResourcePlugin::::default()); + app.add_plugins(ExtractResourcePlugin::::default()); app.init_resource::(); + app.init_resource::(); app.add_systems(PreUpdate, setup_xr.run_if(on_event::())) .add_systems(PreUpdate, cleanup_xr.run_if(on_event::())); app.add_systems(