From 8716021244cb36573fc1c9287dbbd63362bd9552 Mon Sep 17 00:00:00 2001 From: Lubos Date: Wed, 9 Nov 2022 17:59:14 +0100 Subject: [PATCH 1/3] OpenXR - Do not apply head rotation on identity matrix --- Common/VR/PPSSPPVR.cpp | 19 ++++++------------- Common/VR/VRMath.cpp | 14 ++++++++++++++ Common/VR/VRMath.h | 1 + 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 8513500b86..0da404125e 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -644,20 +644,8 @@ bool Is2DVRObject(float* projMatrix, bool ortho) { return true; } - // Chceck if the projection matrix is identity - bool identity = true; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - float value = projMatrix[i * 4 + j]; - - // Other number than zero on non-diagonale - if ((i != j) && (fabs(value) > EPSILON)) identity = false; - // Other number than one on diagonale - if ((i == j) && (fabs(value - 1.0f) > EPSILON)) identity = false; - } - } - // Update 3D geometry count + bool identity = IsMatrixIdentity(projMatrix); if (!identity && !ortho) { vr3DGeometryCount++; } @@ -708,6 +696,11 @@ void UpdateVRView(float* leftEye, float* rightEye) { float* matrix[] = {vrMatrix[VR_VIEW_MATRIX_LEFT_EYE], vrMatrix[VR_VIEW_MATRIX_RIGHT_EYE]}; for (int index = 0; index < 2; index++) { + // Validate the view matrix + if (IsMatrixIdentity(dst[index])) { + return; + } + // Get view matrix from the game Lin::Matrix4x4 gameView = {}; memcpy(gameView.m, dst[index], 16 * sizeof(float)); diff --git a/Common/VR/VRMath.cpp b/Common/VR/VRMath.cpp index 2fd7f1d538..d65f13a1a7 100644 --- a/Common/VR/VRMath.cpp +++ b/Common/VR/VRMath.cpp @@ -13,6 +13,20 @@ float ToRadians(float deg) { return (float)(deg * M_PI / 180.0f); } +bool IsMatrixIdentity(float* matrix) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + float value = matrix[i * 4 + j]; + + // Other number than zero on non-diagonale + if ((i != j) && (fabs(value) > EPSILON)) return false; + // Other number than one on diagonale + if ((i == j) && (fabs(value - 1.0f) > EPSILON)) return false; + } + } + return true; +} + /* ================================================================================ diff --git a/Common/VR/VRMath.h b/Common/VR/VRMath.h index 20317f4a8d..4f6e0610c9 100644 --- a/Common/VR/VRMath.h +++ b/Common/VR/VRMath.h @@ -9,6 +9,7 @@ float ToDegrees(float rad); float ToRadians(float deg); +bool IsMatrixIdentity(float* matrix); // XrPosef XrPosef XrPosef_Identity(); From b980f55645da1d312c903806d8d36b428e7accfd Mon Sep 17 00:00:00 2001 From: Lubos Date: Wed, 9 Nov 2022 19:07:45 +0100 Subject: [PATCH 2/3] OpenXR - Don't get mirroring from identity matrix --- Common/VR/PPSSPPVR.cpp | 4 ++-- Common/VR/PPSSPPVR.h | 2 +- GPU/GLES/ShaderManagerGLES.cpp | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 0da404125e..eff2c37525 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -652,10 +652,10 @@ bool Is2DVRObject(float* projMatrix, bool ortho) { return identity; } -void UpdateVRParams(float* projMatrix) { +void UpdateVRParams(float* projMatrix, float* viewMatrix) { // Set mirroring of axes - if (!vrMirroring[VR_MIRRORING_UPDATED]) { + if (!vrMirroring[VR_MIRRORING_UPDATED] && !IsMatrixIdentity(projMatrix) && !IsMatrixIdentity(viewMatrix)) { vrMirroring[VR_MIRRORING_UPDATED] = true; vrMirroring[VR_MIRRORING_AXIS_X] = projMatrix[0] < 0; vrMirroring[VR_MIRRORING_AXIS_Y] = projMatrix[5] < 0; diff --git a/Common/VR/PPSSPPVR.h b/Common/VR/PPSSPPVR.h index 8dd127a2cb..c47fada705 100644 --- a/Common/VR/PPSSPPVR.h +++ b/Common/VR/PPSSPPVR.h @@ -40,6 +40,6 @@ int GetVRPassesCount(); bool IsMultiviewSupported(); bool IsFlatVRScene(); bool Is2DVRObject(float* projMatrix, bool ortho); -void UpdateVRParams(float* projMatrix); +void UpdateVRParams(float* projMatrix, float* viewMatrix); void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye); void UpdateVRView(float* leftEye, float* rightEye); diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index aa17822d8c..3ba4a94f95 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -411,7 +411,9 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu } else { UpdateVRProjection(gstate.projMatrix, leftEyeMatrix.m, rightEyeMatrix.m); } - UpdateVRParams(gstate.projMatrix); + float m4x4[16]; + ConvertMatrix4x3To4x4Transposed(m4x4, gstate.viewMatrix); + UpdateVRParams(gstate.projMatrix, m4x4); FlipProjMatrix(leftEyeMatrix, useBufferedRendering); FlipProjMatrix(rightEyeMatrix, useBufferedRendering); From 307acaa9b774b8e5b801618bd880e85cbb5bed4e Mon Sep 17 00:00:00 2001 From: Lubos Date: Wed, 9 Nov 2022 19:25:08 +0100 Subject: [PATCH 3/3] OpenXR - View matrix identity check breaking several games fixed --- Common/VR/PPSSPPVR.cpp | 5 +++-- Core/Compatibility.cpp | 1 + Core/Compatibility.h | 1 + assets/compatvr.ini | 13 +++++++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index eff2c37525..5cd35fc590 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -655,7 +655,8 @@ bool Is2DVRObject(float* projMatrix, bool ortho) { void UpdateVRParams(float* projMatrix, float* viewMatrix) { // Set mirroring of axes - if (!vrMirroring[VR_MIRRORING_UPDATED] && !IsMatrixIdentity(projMatrix) && !IsMatrixIdentity(viewMatrix)) { + bool identityView = PSP_CoreParameter().compat.vrCompat().IdentityViewHack && IsMatrixIdentity(viewMatrix); + if (!vrMirroring[VR_MIRRORING_UPDATED] && !IsMatrixIdentity(projMatrix) && !identityView) { vrMirroring[VR_MIRRORING_UPDATED] = true; vrMirroring[VR_MIRRORING_AXIS_X] = projMatrix[0] < 0; vrMirroring[VR_MIRRORING_AXIS_Y] = projMatrix[5] < 0; @@ -697,7 +698,7 @@ void UpdateVRView(float* leftEye, float* rightEye) { for (int index = 0; index < 2; index++) { // Validate the view matrix - if (IsMatrixIdentity(dst[index])) { + if (PSP_CoreParameter().compat.vrCompat().IdentityViewHack && IsMatrixIdentity(dst[index])) { return; } diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 21fb578456..b09eb67c14 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -122,6 +122,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { } void Compatibility::CheckVRSettings(IniFile &iniFile, const std::string &gameID) { + CheckSetting(iniFile, gameID, "IdentityViewHack", &vrCompat_.IdentityViewHack); CheckSetting(iniFile, gameID, "Skyplane", &vrCompat_.Skyplane); CheckSetting(iniFile, gameID, "UnitsPerMeter", &vrCompat_.UnitsPerMeter); diff --git a/Core/Compatibility.h b/Core/Compatibility.h index c37541ce7a..86d139a536 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -93,6 +93,7 @@ struct CompatFlags { }; struct VRCompat { + bool IdentityViewHack; bool Skyplane; float UnitsPerMeter; }; diff --git a/assets/compatvr.ini b/assets/compatvr.ini index b54081f4f5..b896196ab8 100644 --- a/assets/compatvr.ini +++ b/assets/compatvr.ini @@ -30,6 +30,18 @@ # ======================================================================================== +[IdentityViewHack] +# Disables head tracking for render passes where view matrix is Identity + +# Sonic Rivals 1 +ULES00622 = true +ULUS10195 = true + +# Sonic Rivals 2 +ULES00940 = true +ULUS10323 = true + + [Skyplane] # Workaround to remove the background skyplane and add clearing framebuffer with a fog color. @@ -53,6 +65,7 @@ ULJM05395 = true ULJM05884 = true ULUS10160 = true + [UnitsPerMeter] # Scale of game world to convert the world units into meters. This enables following VR features: # + 3D stereoscopy (that can work only with accurate values)