diff --git a/Cargo.lock b/Cargo.lock index 13c156d..71373c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1242,8 +1242,7 @@ dependencies = [ [[package]] name = "bevy_render" version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef91fed1f09405769214b99ebe4390d69c1af5cdd27967deae9135c550eb1667" +source = "git+https://github.com/Schmarni-Dev/bevy?branch=render_thread_init_callback#2ac1d069738b047d172195c1be990ee29c64a0b2" dependencies = [ "async-channel", "bevy_app", @@ -2962,7 +2961,7 @@ dependencies = [ "log", "presser", "thiserror 1.0.69", - "windows 0.58.0", + "windows 0.54.0", ] [[package]] @@ -3501,7 +3500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.53.2", ] [[package]] @@ -4042,7 +4041,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.104", @@ -5114,7 +5113,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -5743,7 +5742,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix 1.1.2", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6190,7 +6189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69fff37da548239c3bf9e64a12193d261e8b22b660991c6fd2df057c168f435f" dependencies = [ "cc", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -6791,7 +6790,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 828772f..d926160 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ debug = true opt-level = 3 [patch.crates-io] -bevy_mod_openxr = { git = "https://github.com/awtterpip/bevy_oxr", rev = "9fd0c797"} +bevy_mod_openxr = { git = "https://github.com/awtterpip/bevy_oxr", rev = "9fd0c797" } bevy_mod_xr = { git = "https://github.com/awtterpip/bevy_oxr", rev = "9fd0c797" } bevy_gltf = { git = "https://github.com/Schmarni-Dev/bevy", branch = "gltf_backport" } # TODO: figure out how to not need this horrifing patch @@ -71,6 +71,7 @@ naga = { git = "https://github.com/Schmarni-Dev/wgpu", branch = "bad_dmabuf_work wgpu-hal = { git = "https://github.com/Schmarni-Dev/wgpu", branch = "bad_dmabuf_workaround" } bevy_pbr = { git = "https://github.com/Schmarni-Dev/bevy", branch = "premul_oit_016" } bevy_core_pipeline = { git = "https://github.com/Schmarni-Dev/bevy", branch = "premul_oit_016" } +bevy_render = { git = "https://github.com/Schmarni-Dev/bevy", branch = "render_thread_init_callback" } [dependencies] # small utility thingys diff --git a/src/main.rs b/src/main.rs index bfb119e..7090ec1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,6 +29,9 @@ use bevy::gizmos::GizmoPlugin; use bevy::gltf::GltfPlugin; use bevy::input::InputPlugin; use bevy::pbr::PbrPlugin; +use bevy::render::pipelined_rendering::{ + PipelinedRenderThreadOnCreateCallback, PipelinedRenderingPlugin, +}; use bevy::render::settings::{Backends, RenderCreation, WgpuSettings}; use bevy::render::{RenderDebugFlags, RenderPlugin}; use bevy::scene::ScenePlugin; @@ -335,6 +338,9 @@ fn bevy_loop( false => plugins.add(FlatscreenInputPlugin), }; } + app.insert_resource(PipelinedRenderThreadOnCreateCallback( + enter_runtime_context.clone(), + )); app.add_plugins( if !args.force_flatscreen { add_xr_plugins(plugins) @@ -386,6 +392,7 @@ fn bevy_loop( ..default() }), ); + app.add_plugins(PipelinedRenderingPlugin); app.add_plugins(bevy_sk::hand::HandPlugin); app.add_plugins(bevy_equirect::EquirectangularPlugin); @@ -506,3 +513,13 @@ fn xr_step(world: &mut World) { tick_internal_client(); } + +pub fn get_time(pipelined: bool, state: &OxrFrameState) -> openxr::Time { + if pipelined { + openxr::Time::from_nanos( + state.predicted_display_time.as_nanos() + state.predicted_display_period.as_nanos(), + ) + } else { + state.predicted_display_time + } +} diff --git a/src/objects/hmd.rs b/src/objects/hmd.rs index 6169054..525ff14 100644 --- a/src/objects/hmd.rs +++ b/src/objects/hmd.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use bevy::prelude::*; use bevy_mod_openxr::{ helper_traits::{ToQuat as _, ToVec3 as _}, - resources::OxrFrameState, + resources::{OxrFrameState, Pipelined}, session::OxrSession, }; use bevy_mod_xr::{ @@ -12,7 +12,7 @@ use bevy_mod_xr::{ }; use openxr::SpaceLocationFlags; -use crate::{DbusConnection, PreFrameWait, nodes::spatial::Spatial}; +use crate::{DbusConnection, PreFrameWait, get_time, nodes::spatial::Spatial}; use super::{ObjectHandle, SpatialRef, input::mouse_pointer::FlatscreenCam}; @@ -68,6 +68,7 @@ fn update_xr( ref_space: Option>, hmd: Res, state: Option>, + pipelined: Option>, ) { let (Some(session), Some(view), Some(ref_space), Some(state)) = (session, hmd.space, ref_space, state) @@ -80,9 +81,9 @@ fn update_xr( // }); return; }; - // this won't be correct with pipelined rendering + let time = get_time(pipelined.is_some(), &state); let location = session - .locate_space(&view, &ref_space, state.predicted_display_time) + .locate_space(&view, &ref_space, time) .inspect_err(|err| error!("Error while Locating OpenXR Stage Space {err}")); if let Ok(location) = location { let is_tracked = location diff --git a/src/objects/input/oxr_controller.rs b/src/objects/input/oxr_controller.rs index ffe9d84..c400cbc 100644 --- a/src/objects/input/oxr_controller.rs +++ b/src/objects/input/oxr_controller.rs @@ -2,6 +2,7 @@ use super::{CaptureManager, get_sorted_handlers}; use crate::{ DbusConnection, PreFrameWait, core::client::INTERNAL_CLIENT, + get_time, nodes::{ Node, OwnedNode, drawable::{ @@ -19,7 +20,7 @@ use bevy::{math::Affine3, prelude::*}; use bevy_mod_openxr::{ action_binding::{OxrSendActionBindings, OxrSuggestActionBinding}, helper_traits::{ToIsometry3d, ToVec2}, - resources::{OxrFrameState, OxrInstance}, + resources::{OxrFrameState, OxrInstance, Pipelined}, session::OxrSession, }; use bevy_mod_xr::{ @@ -147,6 +148,7 @@ fn update( session: Option>, ref_space: Option>, state: Option>, + pipelined: Option>, ) { let (Some(session), Some(state), Some(ref_space)) = (session, state, ref_space) else { controllers.left.set_enabled(false); @@ -158,8 +160,7 @@ fn update( .sync_actions(&[ActiveActionSet::new(&actions.set)]) .unwrap(); }); - let time = state.predicted_display_time; - // stupid bevy gltf loading issue (rotated 180 degrees on the y axis) + let time = get_time(pipelined.is_some(), &state); controllers .left .update(&session, &actions, time, ref_space.0); diff --git a/src/objects/input/oxr_hand.rs b/src/objects/input/oxr_hand.rs index 366a74b..64613f0 100644 --- a/src/objects/input/oxr_hand.rs +++ b/src/objects/input/oxr_hand.rs @@ -8,11 +8,11 @@ use crate::nodes::{ spatial::Spatial, }; use crate::objects::{AsyncTracked, ObjectHandle, SpatialRef, Tracked}; -use crate::{BevyMaterial, DbusConnection, ObjectRegistryRes, PreFrameWait}; +use crate::{BevyMaterial, DbusConnection, ObjectRegistryRes, PreFrameWait, get_time}; use bevy::prelude::Transform as BevyTransform; use bevy::prelude::*; use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3}; -use bevy_mod_openxr::resources::OxrFrameState; +use bevy_mod_openxr::resources::{OxrFrameState, Pipelined}; use bevy_mod_openxr::session::OxrSession; use bevy_mod_xr::hands::{HandBone, HandSide, XrHandBoneEntities, XrHandBoneRadius}; use bevy_mod_xr::session::{XrPreDestroySession, XrSessionCreated}; @@ -50,6 +50,7 @@ fn update_hands( &mut XrHandBoneRadius, )>, joints_query: Query<&XrHandBoneEntities>, + pipelined: Option>, ) { let (Some(session), Some(state), Some(ref_space)) = (session, state, ref_space) else { hands.left.tracked.set_tracked(false); @@ -62,9 +63,9 @@ fn update_hands( hand.tracked.set_tracked(false); return None; }; - // this won't be correct with pipelined rendering + let time = get_time(pipelined.is_some(), &state); session - .locate_hand_joints(tracker, &ref_space, state.predicted_display_time) + .locate_hand_joints(tracker, &ref_space, time) .inspect_err(|err| error!("Error while locating hand joints")) .ok() .flatten() diff --git a/src/objects/play_space.rs b/src/objects/play_space.rs index df66942..121f7b5 100644 --- a/src/objects/play_space.rs +++ b/src/objects/play_space.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use bevy::prelude::*; use bevy_mod_openxr::{ helper_traits::{ToQuat, ToVec3}, - resources::OxrFrameState, + resources::{OxrFrameState, Pipelined}, session::OxrSession, }; use bevy_mod_xr::{ @@ -14,7 +14,7 @@ use openxr::SpaceLocationFlags; use parking_lot::RwLock; use zbus::{Connection, ObjectServer, interface}; -use crate::{DbusConnection, PreFrameWait, nodes::spatial::Spatial}; +use crate::{DbusConnection, PreFrameWait, get_time, nodes::spatial::Spatial}; use super::{AsyncTracked, ObjectHandle, SpatialRef, Tracked}; @@ -75,6 +75,7 @@ fn update( ref_space: Option>, play_space: Res, state: Option>, + pipelined: Option>, ) { let (Some(session), Some(stage), Some(ref_space), Some(state)) = (session, stage, ref_space, state) @@ -87,9 +88,9 @@ fn update( .set_local_transform(Mat4::from_translation(vec3(0.0, -1.65, 0.0))); return; }; - // this won't be correct with pipelined rendering + let time = get_time(pipelined.is_some(), &state); let location = session - .locate_space(&stage.0, &ref_space, state.predicted_display_time) + .locate_space(&stage.0, &ref_space, time) .inspect_err(|err| error!("Error while Locating OpenXR Stage Space {err}")); if let Ok(location) = location { let is_tracked = location.location_flags.contains( diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index bebd689..0e9fe10 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -11,6 +11,7 @@ mod xdg; use crate::core::error::ServerError; use crate::core::registry::OwnedRegistry; +use crate::get_time; use crate::nodes::drawable::model::ModelNodeSystemSet; use crate::wayland::core::seat::SeatMessage; use crate::wayland::core::surface::Surface; @@ -26,7 +27,7 @@ use bevy::render::{Render, RenderApp}; use bevy::{asset::Assets, ecs::resource::Resource, image::Image}; use bevy_dmabuf::import::ImportedDmatexs; use bevy_mod_openxr::render::end_frame; -use bevy_mod_openxr::resources::{OxrFrameState, OxrInstance}; +use bevy_mod_openxr::resources::{OxrFrameState, OxrInstance, Pipelined}; use bevy_mod_xr::session::XrRenderSet; use core::buffer::BufferUsage; use core::{buffer::Buffer, callback::Callback, surface::WL_SURFACE_REGISTRY}; @@ -490,6 +491,7 @@ fn submit_frame_timings( mut frame_count: Local, instance: Option>, frame_state: Option>, + pipelined: Option>, ) { *frame_count += 1; let display_timestamp = frame_state @@ -502,7 +504,7 @@ fn submit_frame_timings( let mut out = MaybeUninit::uninit(); let result = (v.convert_time_to_timespec_time)( instance.as_raw(), - state.predicted_display_time, + get_time(pipelined.is_some(), &state), out.as_mut_ptr(), ); if result != openxr::sys::Result::SUCCESS {