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 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<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 {
DefaultPlugins
.build()
.disable::<PipelinedRenderingPlugin>()
.disable::<RenderPlugin>()
// .disable::<PipelinedRenderingPlugin>()
.add_before::<RenderPlugin, _>(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<XrShouldRender>) {
fn xr_reset_per_frame_resources(mut should: ResMut<XrShouldRender>,mut waited: ResMut<XrHasWaited>) {
**should = false;
**waited = false;
}
fn xr_poll_events(
@@ -271,6 +296,7 @@ pub fn xr_wait_frame(
mut frame_state: ResMut<XrFrameState>,
mut frame_waiter: ResMut<XrFrameWaiter>,
mut should_render: ResMut<XrShouldRender>,
mut waited: ResMut<XrHasWaited>,
) {
{
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;
}
}

View File

@@ -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<Res<XrStatus>>) -> bool {
resource_exists_and_equals(XrStatus::Enabled)
pub fn xr_only() -> impl FnMut(Res<XrStatus>) -> bool {
resource_equals(XrStatus::Enabled)
}
pub fn xr_render_only() -> impl FnMut(Option<Res<XrShouldRender>>) -> bool {
resource_exists_and_equals(XrShouldRender(true))
pub fn xr_render_only() -> impl FnMut(Res<XrShouldRender>) -> bool {
resource_equals(XrShouldRender(true))
}
pub fn xr_after_wait_only() -> impl FnMut(Res<XrHasWaited>) -> bool {
resource_equals(XrHasWaited(true))
}
impl Plugin for XrEarlyInitPlugin {
@@ -59,7 +66,9 @@ impl Plugin for XrInitPlugin {
add_schedules(app);
app.add_plugins(ExtractResourcePlugin::<XrStatus>::default());
app.add_plugins(ExtractResourcePlugin::<XrShouldRender>::default());
app.add_plugins(ExtractResourcePlugin::<XrHasWaited>::default());
app.init_resource::<XrShouldRender>();
app.init_resource::<XrHasWaited>();
app.add_systems(PreUpdate, setup_xr.run_if(on_event::<SetupXrData>()))
.add_systems(PreUpdate, cleanup_xr.run_if(on_event::<CleanupXrData>()));
app.add_systems(