From 0ff0742e4fd378753a0d6b00c5f364f1944ca687 Mon Sep 17 00:00:00 2001 From: Asxcvbn Date: Sun, 14 Sep 2025 14:19:59 +0800 Subject: [PATCH 1/2] request force right_fov sync every 100 frames --- src/mods/vr/runtimes/OpenXR.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mods/vr/runtimes/OpenXR.cpp b/src/mods/vr/runtimes/OpenXR.cpp index 02602e0e9..c18a194cf 100644 --- a/src/mods/vr/runtimes/OpenXR.cpp +++ b/src/mods/vr/runtimes/OpenXR.cpp @@ -553,9 +553,13 @@ VRRuntime::Error OpenXR::update_matrices(float nearz, float farz) { }; }; + static long int frame_count = -1; + frame_count++; + + // if we've not yet derived an eye projection matrix, or we've changed the projection, derive it here // Hacky way to check for an uninitialised eye matrix - is there something better, is this necessary? - if (this->should_recalculate_eye_projections || this->last_eye_matrix_nearz != nearz || this->projections[0][2][3] == 0) { + if (this->should_recalculate_eye_projections || this->last_eye_matrix_nearz != nearz || this->projections[0][2][3] == 0 || frame_count % 100 == 0) { // deriving the texture bounds when modifying projections requires left and right raw projections so get them all before we start: std::unique_lock __{this->eyes_mtx}; const auto& left_fov = this->views[0].fov; From a9d3f21ce3169f0897040e741cfb941e08979a34 Mon Sep 17 00:00:00 2001 From: Asxcvbn Date: Fri, 19 Sep 2025 16:44:15 +0800 Subject: [PATCH 2/2] respect convergence changes by updateing projections in frames that views.fov changed --- src/mods/vr/runtimes/OpenXR.cpp | 14 ++++++++++---- src/mods/vr/runtimes/OpenXR.hpp | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/mods/vr/runtimes/OpenXR.cpp b/src/mods/vr/runtimes/OpenXR.cpp index c18a194cf..93d2074da 100644 --- a/src/mods/vr/runtimes/OpenXR.cpp +++ b/src/mods/vr/runtimes/OpenXR.cpp @@ -553,13 +553,14 @@ VRRuntime::Error OpenXR::update_matrices(float nearz, float farz) { }; }; - static long int frame_count = -1; - frame_count++; - + bool fov_updated = ( + memcmp(&this->views[0].fov, &this->last_fovs[0], sizeof(XrFovf)) != 0 + || memcmp(&this->views[1].fov, &this->last_fovs[1], sizeof(XrFovf)) != 0 + ); // XrFovf is a POD type, so we compare it byte-by-byte // if we've not yet derived an eye projection matrix, or we've changed the projection, derive it here // Hacky way to check for an uninitialised eye matrix - is there something better, is this necessary? - if (this->should_recalculate_eye_projections || this->last_eye_matrix_nearz != nearz || this->projections[0][2][3] == 0 || frame_count % 100 == 0) { + if (this->should_recalculate_eye_projections || this->last_eye_matrix_nearz != nearz || this->projections[0][2][3] == 0 || fov_updated) { // deriving the texture bounds when modifying projections requires left and right raw projections so get them all before we start: std::unique_lock __{this->eyes_mtx}; const auto& left_fov = this->views[0].fov; @@ -576,6 +577,11 @@ VRRuntime::Error OpenXR::update_matrices(float nearz, float farz) { this->projections[1] = get_mat(1); this->should_recalculate_eye_projections = false; this->last_eye_matrix_nearz = nearz; + + if (fov_updated) { + this->last_fovs[0] = this->views[0].fov; + this->last_fovs[1] = this->views[1].fov; + } } // don't allow the eye matrices to be derived again until after the next frame sync this->should_update_eye_matrices = false; diff --git a/src/mods/vr/runtimes/OpenXR.hpp b/src/mods/vr/runtimes/OpenXR.hpp index 929923a4a..d5a5681d9 100644 --- a/src/mods/vr/runtimes/OpenXR.hpp +++ b/src/mods/vr/runtimes/OpenXR.hpp @@ -212,6 +212,9 @@ struct OpenXR final : public VRRuntime { std::vector views{}; std::vector stage_views{}; + std::array last_fovs{}; + + //std::deque> stage_view_queue{}; struct PipelineState { XrFrameState frame_state{XR_TYPE_FRAME_STATE};