From 5575806fbf188cfc822eaee0abde7ad2289e688b Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Feb 2026 05:06:12 +0000 Subject: [PATCH 1/3] add OpenXR extra copy for non-rendered eye in async AER When async AER is enabled for D3D11+OpenXR, each frame now copies both eye swapchains - the rendered eye and the cached non-rendered eye. This keeps acquire/wait/release balanced per swapchain. https://claude.ai/code/session_0113R4SbhVpihniGsyFqv6vP --- src/mods/vr/D3D11Component.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mods/vr/D3D11Component.cpp b/src/mods/vr/D3D11Component.cpp index ed39485..6fca2d8 100644 --- a/src/mods/vr/D3D11Component.cpp +++ b/src/mods/vr/D3D11Component.cpp @@ -299,6 +299,12 @@ vr::EVRCompositorError D3D11Component::on_frame(VR* vr) { if (runtime->is_openxr() && runtime->ready()) { LOG_VERBOSE("Copying left eye"); m_openxr.copy(0, (ID3D11Texture2D*)copy_from_tex.Get()); + + if (vr->is_using_async_aer()) { + auto right_eye_source = backbufferIs8Bit ? m_right_eye_tex : m_right_eye_rt.tex; + LOG_VERBOSE("Copying right eye (async AER extra copy)"); + m_openxr.copy(1, (ID3D11Texture2D*)right_eye_source.Get()); + } } if (runtime->is_openvr()) { @@ -365,6 +371,12 @@ vr::EVRCompositorError D3D11Component::on_frame(VR* vr) { if (runtime->ready() && runtime->is_openxr()) { LOG_VERBOSE("Copying right eye"); m_openxr.copy(1, (ID3D11Texture2D*)copy_from_tex.Get()); + + if (vr->is_using_async_aer()) { + auto left_eye_source = backbufferIs8Bit ? m_left_eye_tex : m_left_eye_rt.tex; + LOG_VERBOSE("Copying left eye (async AER extra copy)"); + m_openxr.copy(0, (ID3D11Texture2D*)left_eye_source.Get()); + } } if (runtime->is_openvr()) { From f30522dfed5262e94b76333886bc94dd78ca34ed Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Feb 2026 05:13:56 +0000 Subject: [PATCH 2/3] fix right eye flickering in 8-bit path for async AER Add missing copy from backbuffer to m_right_eye_tex in the right eye frame for the 8-bit OpenXR path. Without this, the cached right eye texture used during left eye frames contained stale/uninitialized data. https://claude.ai/code/session_0113R4SbhVpihniGsyFqv6vP --- src/mods/vr/D3D11Component.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mods/vr/D3D11Component.cpp b/src/mods/vr/D3D11Component.cpp index 6fca2d8..831b362 100644 --- a/src/mods/vr/D3D11Component.cpp +++ b/src/mods/vr/D3D11Component.cpp @@ -366,6 +366,8 @@ vr::EVRCompositorError D3D11Component::on_frame(VR* vr) { m_toneMap->SetExposure(settings.toneMapExposure); m_toneMap->SetHDRSourceTexture(m_backbuffer_copy_rt); m_toneMap->Process(context.Get()); + } else if (backbufferIs8Bit) { + context->CopyResource(m_right_eye_tex.Get(), backbuffer.Get()); } if (runtime->ready() && runtime->is_openxr()) { From 143012386deff32c51172136c6af4a1fc1dd9df5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Feb 2026 05:24:33 +0000 Subject: [PATCH 3/3] enable async AER for D3D11 OpenXR Remove the DX12-only restriction from is_using_async_aer() to also allow D3D11 when using OpenXR runtime. OpenVR on D3D11 remains disabled due to pose handling issues with non-Steam native VR HMDs. https://claude.ai/code/session_0113R4SbhVpihniGsyFqv6vP --- src/mods/VR.hpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mods/VR.hpp b/src/mods/VR.hpp index 1ae8809..b17d2f8 100644 --- a/src/mods/VR.hpp +++ b/src/mods/VR.hpp @@ -136,10 +136,13 @@ class VR : public Mod { // int32_t get_game_frame_count() const; bool is_using_async_aer() const { - // openVR has issues with 2 different poses at the same time for non steam native VR hmds like oculus - // for these exceptions need to implement viewport cropping and viewport reprojection - //TODO it looks like runtime does not fully support dx11 reprojeciton, I need to do it manually - return m_use_async_aer->value() && g_framework->is_dx12(); + if (!m_use_async_aer->value()) { + return false; + } + if (g_framework->is_dx12()) { + return true; + } + return get_runtime()->is_openxr(); } bool is_gui_enabled() const {