implement simple pipelined rendering

This commit is contained in:
Schmarni
2024-01-25 06:39:44 +01:00
parent a3c33cb8b6
commit 9d6d60cbe7
2 changed files with 49 additions and 13 deletions

View File

@@ -33,7 +33,7 @@ use openxr as xr;
use resources::*; use resources::*;
use xr::{FormFactor, FrameState}; use xr::{FormFactor, FrameState};
use xr_init::{ 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::controllers::XrControllerType;
use xr_input::hands::emulated::HandEmulationPlugin; use xr_input::hands::emulated::HandEmulationPlugin;
@@ -118,7 +118,7 @@ impl Plugin for OpenXrPlugin {
app.add_systems( app.add_systems(
PreUpdate, PreUpdate,
( (
xr_reset_should_render, xr_reset_per_frame_resources,
xr_wait_frame.run_if(xr_only()), xr_wait_frame.run_if(xr_only()),
locate_views.run_if(xr_only()), locate_views.run_if(xr_only()),
apply_deferred, apply_deferred,
@@ -130,15 +130,15 @@ impl Plugin for OpenXrPlugin {
render_app.add_systems( render_app.add_systems(
Render, Render,
xr_begin_frame xr_begin_frame
.run_if(xr_only()) .run_if(xr_only()).run_if(xr_after_wait_only())
.run_if(xr_render_only()) // .run_if(xr_render_only())
.after(RenderSet::ExtractCommands) .after(RenderSet::ExtractCommands)
.before(xr_pre_frame), .before(xr_pre_frame),
); );
render_app.add_systems( render_app.add_systems(
Render, Render,
xr_pre_frame xr_pre_frame
.run_if(xr_only()) .run_if(xr_only()).run_if(xr_after_wait_only())
.run_if(xr_render_only()) .run_if(xr_render_only())
// Do NOT touch this ordering! idk why but you can NOT just put in a RenderSet // Do NOT touch this ordering! idk why but you can NOT just put in a RenderSet
// right before rendering // right before rendering
@@ -162,10 +162,34 @@ impl Plugin for OpenXrPlugin {
render_app.add_systems( render_app.add_systems(
Render, Render,
xr_end_frame xr_end_frame
.run_if(xr_only()) .run_if(xr_only()).run_if(xr_after_wait_only())
.run_if(xr_render_only()) .run_if(xr_render_only())
.after(RenderSet::Render), .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<XrSwapchain>,
xr_frame_state: Res<XrFrameState>,
environment_blend_mode: Res<XrEnvironmentBlendMode>,
) {
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 { fn build(self) -> PluginGroupBuilder {
DefaultPlugins DefaultPlugins
.build() .build()
.disable::<PipelinedRenderingPlugin>()
.disable::<RenderPlugin>() .disable::<RenderPlugin>()
// .disable::<PipelinedRenderingPlugin>()
.add_before::<RenderPlugin, _>(OpenXrPlugin { .add_before::<RenderPlugin, _>(OpenXrPlugin {
prefered_blend_mode: self.prefered_blend_mode, prefered_blend_mode: self.prefered_blend_mode,
reqeusted_extensions: self.reqeusted_extensions, reqeusted_extensions: self.reqeusted_extensions,
@@ -211,8 +235,9 @@ impl PluginGroup for DefaultXrPlugins {
} }
} }
fn xr_reset_should_render(mut should: ResMut<XrShouldRender>) { fn xr_reset_per_frame_resources(mut should: ResMut<XrShouldRender>,mut waited: ResMut<XrHasWaited>) {
**should = false; **should = false;
**waited = false;
} }
fn xr_poll_events( fn xr_poll_events(
@@ -271,6 +296,7 @@ pub fn xr_wait_frame(
mut frame_state: ResMut<XrFrameState>, mut frame_state: ResMut<XrFrameState>,
mut frame_waiter: ResMut<XrFrameWaiter>, mut frame_waiter: ResMut<XrFrameWaiter>,
mut should_render: ResMut<XrShouldRender>, mut should_render: ResMut<XrShouldRender>,
mut waited: ResMut<XrHasWaited>,
) { ) {
{ {
let _span = info_span!("xr_wait_frame").entered(); 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 = xr::Time::from_nanos(
frame_state.predicted_display_time.as_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"); info!("Post Frame Wait");
**should_render = frame_state.should_render; **should_render = frame_state.should_render;
**waited = true;
} }
} }

View File

@@ -33,16 +33,23 @@ pub enum XrStatus {
Resource, Clone, Copy, PartialEq, Eq, Reflect, Debug, ExtractResource, Default, Deref, DerefMut, Resource, Clone, Copy, PartialEq, Eq, Reflect, Debug, ExtractResource, Default, Deref, DerefMut,
)] )]
pub struct XrShouldRender(bool); 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 XrEarlyInitPlugin;
pub struct XrInitPlugin; pub struct XrInitPlugin;
pub fn xr_only() -> impl FnMut(Option<Res<XrStatus>>) -> bool { pub fn xr_only() -> impl FnMut(Res<XrStatus>) -> bool {
resource_exists_and_equals(XrStatus::Enabled) resource_equals(XrStatus::Enabled)
} }
pub fn xr_render_only() -> impl FnMut(Option<Res<XrShouldRender>>) -> bool { pub fn xr_render_only() -> impl FnMut(Res<XrShouldRender>) -> bool {
resource_exists_and_equals(XrShouldRender(true)) resource_equals(XrShouldRender(true))
}
pub fn xr_after_wait_only() -> impl FnMut(Res<XrHasWaited>) -> bool {
resource_equals(XrHasWaited(true))
} }
impl Plugin for XrEarlyInitPlugin { impl Plugin for XrEarlyInitPlugin {
@@ -59,7 +66,9 @@ impl Plugin for XrInitPlugin {
add_schedules(app); add_schedules(app);
app.add_plugins(ExtractResourcePlugin::<XrStatus>::default()); app.add_plugins(ExtractResourcePlugin::<XrStatus>::default());
app.add_plugins(ExtractResourcePlugin::<XrShouldRender>::default()); app.add_plugins(ExtractResourcePlugin::<XrShouldRender>::default());
app.add_plugins(ExtractResourcePlugin::<XrHasWaited>::default());
app.init_resource::<XrShouldRender>(); app.init_resource::<XrShouldRender>();
app.init_resource::<XrHasWaited>();
app.add_systems(PreUpdate, setup_xr.run_if(on_event::<SetupXrData>())) app.add_systems(PreUpdate, setup_xr.run_if(on_event::<SetupXrData>()))
.add_systems(PreUpdate, cleanup_xr.run_if(on_event::<CleanupXrData>())); .add_systems(PreUpdate, cleanup_xr.run_if(on_event::<CleanupXrData>()));
app.add_systems( app.add_systems(