Releases: djules75/OFXR-Bridge
Release list
OFXR Bridge v0.2.7.3 (V365)
An unofficial build on
tig3rmast3r's v0.2.1.
A maintenance release after 0.2.7.2.
What's new
- Vulkan support is on by default. Vulkan games, such as No Man's Sky
through OpenComposite, now get frame generation without any setting. The
tray no longer has a Vulkan support menu entry. While the bridge is
armed, its small Vulkan layer is registered, and it loads into every
Vulkan application, browsers included. It is removed when you disarm or
close the tray. - Less VRAM with the NVIDIA optical flow. The optical-flow engine now
receives a single brightness channel instead of full colour. It tracks
motion just as well from brightness, and its input textures take a quarter
of the memory. See the table below for how much that saves. GPU time is
unchanged. - Steadier repeating patterns during head movement with the NVIDIA
optical flow. Before the optical flow runs, the previous frame is now
aligned to your current head position, so the engine only has to find
what moved in the scene itself. Tiles, grids and other repeating textures
hold steadier while you turn your head, and moving objects keep their own
motion during a head turn. GPU time is unchanged.
The FidelityFX optical flow is unchanged.
VRAM saved with the NVIDIA optical flow
The saving depends on your per-eye resolution and the Optical flow
resolution setting in the tray. It is the same whether the game uses one
image for both eyes or one per eye. These figures are calculated from the
texture sizes, not measured.
| Per-eye resolution | Example | 50% (default) | 75% | 100% |
|---|---|---|---|---|
| 2000 × 2000 | Quest 3 at moderate settings | 36 MB | 81 MB | 144 MB |
| 3088 × 3088 | Pimax Crystal at a lower resolution | 86 MB | 193 MB | 343 MB |
| 4172 × 3268 | Ready or Not or MSFS 2024 on a Pimax Crystal Super | 123 MB | 276 MB | 491 MB* |
| 5092 × 3988 | MSFS 2024 at a high resolution | 183 MB | 411 MB | 731 MB* |
* Only in games that use one image per eye, such as MSFS 2024. Games that
put both eyes in one image, such as Ready or Not, cannot use 100% at these
resolutions: the image is too wide for the optical-flow engine.
Known issues
- SteamVR: turn off Motion Smoothing and "fixed frame rate at half" for
the game in SteamVR's per-application video settings. When a game's GPU
time reaches the refresh budget, SteamVR starts halving its frame rate on
and off, and the bridge's pairs land late: the result is stutter and a
performance drop that looks like a bridge regression. Check this first. - No FPS overlay in Vulkan games. Vulkan games have no reliable FPS
reading yet. - Dips are often a resolution ceiling, not the bridge. Disarm the bridge
and play the same scene: if the dips remain, lower the per-eye resolution. - Pick a refresh rate close to double your game's frame rate. If double
is still short of the refresh rate, the bridge fills the difference with
repeated frames and the image judders. The FPS number shows when this is
happening.
Installing
Unzip anywhere and run OFXRBridgeTray.exe. It arms the bridge by itself.
Keep OFXRBridgeTray.exe and the ofxr folder together; it holds the OpenXR
layer, its settings and the Vulkan layer. If an earlier version is armed,
disarm it and close its tray first.
Tested
With a Pimax Crystal Super on an RTX 5090, on SteamVR
Please report results, working or not, on this fork's
GitHub Issues, with an OFXR flight log where you can. To
record one, enable Bridge flight recorder in the tray, reproduce the
problem, then use Open bridge logs. Logs are written under
%LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v365\.
OFXR Bridge v0.2.7.2 (V337)
An unofficial build on
tig3rmast3r's v0.2.1.
A minor follow-up to 0.2.7. Frame generation itself is unchanged.
What's new
- The OFXR FPS number no longer over-reports when the game drops below
half the refresh rate. Each game frame becomes two frames in the headset:
the real one and a generated one. Below half rate, for example under 45 FPS
on a 90 Hz headset, there are not enough of them to fill every refresh, so
the bridge shows the last frame again. On SteamVR the FPS number counted
those repeats as new frames and read the full refresh rate. In Callisto
Protocol at high resolution it showed 90 while only 73 new frames a second
reached the headset. It now counts only new frames. Above half rate there
are no repeats, and the number reads the same as before.
Which FPS number to trust
Use the OFXR FPS number. It is the only counter that sees both how the
bridge built each frame and what SteamVR did with it.
Other tools can read wrong while the bridge is active:
- fpsVR, SteamVR's frame timing and other compositor-side tools count
every frame the bridge hands to SteamVR. They cannot tell a repeated frame
from a new one, so below half rate they still show the full refresh rate.
This release does not change what they show. - Counters inside the game or the VR mod, and some setups of xrFPS, count
the game's own frames before the bridge adds any. While generation is on
they show about half of what reaches the headset.
Known issues
- SteamVR: turn off Motion Smoothing and "fixed frame rate at half" for
the game in SteamVR's per-application video settings. When a game's GPU
time reaches the refresh budget, SteamVR starts halving its frame rate on
and off, and the bridge's pairs land late: the result is stutter and a
performance drop that looks like a bridge regression. Check this first. - No FPS overlay in Vulkan games. Unchanged since 0.2.5, so Vulkan games
have no reliable FPS reading yet. - Dips are often a resolution ceiling, not the bridge. Disarm the bridge
and play the same scene: if the dips remain, lower the per-eye resolution. - Pick a refresh rate close to double your game's frame rate. If double
is still short of the refresh rate, the bridge fills the difference with
repeated frames and the image judders. The FPS number now shows when this
is happening.
Installing
Unzip anywhere and run OFXRBridgeTray.exe. It arms the bridge by itself.
Keep OFXRBridgeTray.exe and the ofxr folder together; it holds the OpenXR
layer, its settings and the Vulkan layer. If an earlier version is armed,
disarm it and close its tray first.
Tested
With a Pimax Crystal Super on an RTX 5090:
- Callisto Protocol at high resolution on SteamVR, the session that
showed the problem
Please report results, working or not, on this fork's
GitHub Issues, with an OFXR flight log where you can. To
record one, enable Bridge flight recorder in the tray, reproduce the
problem, then use Open bridge logs. Logs are written under
%LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v337\.
OFXR Bridge v0.2.7 (V336)
An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.6.
What's new
- Ready or Not with the VRO mod is supported. On 0.2.6 the headset
showed a black screen while the FPS number sat red at the full refresh
rate. It now runs with frame generation on SteamVR and Virtual Desktop.
Two fixes made that work, and both can matter to other games. - Games that acquire swapchain images ahead of rendering no longer lose
frame generation. Some games grab their next image before they need it,
or before their OpenXR session has started. The bridge lost track of which
image the game was holding and stopped generating for the rest of the
session. On most games that meant a red FPS number and half the frame
rate. On D3D11 games, which since 0.2.6 go through the D3D11 bridge, it
meant a black screen, because that tracking decides which image reaches
the headset. This affects every graphics API, not only D3D11. - D3D11 games that use a packed depth-stencil format no longer have their
depth swapchain refused. D3D11 cannot share these formats with the
bridge's D3D12 device, so the bridge used to fail the game's request.
Ready or Not carried on without it; other games might not. The game now
keeps its depth on its own side, and the bridge submits frames without
depth information, as most games do anyway.
Known issues
- SteamVR: turn off Motion Smoothing and "fixed frame rate at half" for
the game in SteamVR's per-application video settings. When a game's GPU
time reaches the refresh budget, SteamVR starts halving its frame rate on
and off, and the bridge's pairs land late: the result is stutter and a
performance drop that looks like a bridge regression. Check this first. - No FPS overlay in Vulkan games. Unchanged since 0.2.5.
- Dips are often a resolution ceiling, not the bridge. Disarm the bridge
and play the same scene: if the dips remain, lower the per-eye resolution. - Pick a refresh rate close to double your game's frame rate. If double
is still short of the refresh rate, the bridge fills the difference with
repeated frames and the image judders.
Installing
Unzip anywhere and run OFXRBridgeTray.exe. It arms the bridge by itself.
Keep OFXRBridgeTray.exe and the ofxr folder together; it holds the OpenXR
layer, its settings and the Vulkan layer. If an earlier version is armed,
disarm it and close its tray first.
Tested
With a Pimax Crystal Super on an RTX 5090:
- Ready or Not with the VRO mod (D3D11) on SteamVR and Virtual Desktop,
including a session restart mid-game - Hogwarts Legacy (UEVR, D3D12) on SteamVR, unchanged
- No Man's Sky through OpenComposite (Vulkan) on SteamVR, unchanged
Please report results, working or not, on this fork's
GitHub Issues, with an OFXR flight log where you can. To
record one, enable Bridge flight recorder in the tray, reproduce the
problem, then use Open bridge logs. Logs are written under
%LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v336\.
Using the SignPath Foundation for code signing
OFXR Bridge v0.2.6 (V334)
An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.5.
What's new
- A rewritten pipeline for D3D11 games: the D3D11 bridge. Every D3D11
game now runs on the same path as a native D3D12 game. The bridge gives the
OpenXR runtime a D3D12 session on the bridge's own device and the game
renders straight into textures shared with it, so the runtime never touches
the game's D3D11 device again. That removes the NVIDIA D3D11 driver crash
that froze DCS World and SkyrimVR, gives D3D11 games the SteamVR pacing that
D3D12 games already had, and saves one GPU copy per generated frame. On by
default. Tested with DCS World, Assetto Corsa, SkyrimVR and Cyberpunk 2077,
on SteamVR and Virtual Desktop. - DCS World is supported. It froze before the menu, or a few seconds into
a mission (this fork's issues #2 and #3). Both are fixed: the bridge now
follows DCS's frame loop, which waits for the next frame on a second thread
while the current one is still being rendered, and the driver crash at
mission start is gone with the new D3D11 path above. Runs on SteamVR and
Virtual Desktop. - Eye tracking works with Cheeky Foveated DLSS. With the bridge armed,
Cheeky reported "Eye tracking unavailable or awaiting mapping" and fell
back to a fixed sharp region, on every runtime (Cheeky's issue #37).
Cheeky asks the layer beneath it whether the headset
offers eye tracking before the OpenXR instance exists, and the bridge
answered "no". It now answers correctly, and gaze drives the foveation
with the bridge armed exactly as without it.
The D3D11 bridge
Nothing to set up. A D3D11 game gets the bridge automatically when the
runtime offers D3D12, which SteamVR, Virtual Desktop and PimaxXR all do; a
runtime without D3D12 keeps the previous path.
What changed underneath. Until now, a D3D11 game and the OpenXR runtime
shared the game's D3D11 device, and the bridge moved every frame across into
its own D3D12 device for optical flow and moved the results back. NVIDIA's
D3D11 driver could crash when the bridge's presenter thread drove the
runtime's work on that shared device, which is what killed DCS World and
SkyrimVR at mission start. Now the runtime's session lives on the bridge's
D3D12 device from the start. The game still renders in D3D11, into textures
the bridge shares between the two devices, and everything after that,
generation, pacing and submission, is the D3D12 path that UEVR games already
use. Depth, multisampled and mipmapped swapchains are carried across by copy
or resolve where the two APIs cannot share them directly.
Turning it off, for diagnosis only: close the tray, set d3d11_bridge=0
under [tray] in %LOCALAPPDATA%\OFXR Bridge\tray.ini, and start the tray
again. There is no menu entry, and editing the ofxr_bridge.ini beside the
tray does nothing, because the tray rewrites the layer's settings from
tray.ini every time it arms.
Other changes
- NVIDIA Medium is the default backend, with a silent fallback to
FidelityFX on GPUs where NVIDIA optical flow cannot start (AMD, Intel, and
NVIDIA cards without the hardware). This closes 0.2.5's known issue where
selecting NVIDIA on such a card silently did nothing. The tray keeps
showing the selection you made; the flight log records when the fallback
ran. If you are upgrading, the tray keeps the backend you had chosen
before, so select NVIDIA Medium in the menu once if you want the new
default. - Games that run their next-frame wait on another thread, DCS's shape, no
longer deadlock against a runtime that holds that wait until the current
frame is begun, which SteamVR does.
Known issues
- Packed depth-stencil swapchains (
D24_UNORM_S8_UINT,
D32_FLOAT_S8X24_UINT) are untested on the D3D11 bridge. The common VR
depth formats,D32_FLOATandD16_UNORM, are covered. - Cheeky Foveated DLSS at high resolutions can show a flashing grid of
small white coded squares and fail to lock its eye calibration. That is
Cheeky's own calibration, not the bridge: it happens without the bridge
armed too, and Cheeky's Standard corners calibration method avoids it.
Set your resolution before launching the game; every change restarts
Cheeky's calibration. - No FPS overlay in Vulkan games. Unchanged from 0.2.5.
- SteamVR: turn off "fixed frame rate at half" and Motion Smoothing for the
game in SteamVR's per-application video settings, or SteamVR holds the
game to half rate and the bridge can only deliver half. - Dips are often a resolution ceiling, not the bridge. Disarm the bridge
and play the same scene: if the dips remain, lower the per-eye resolution. - Pick a refresh rate close to double your game's frame rate. If double
is still short of the refresh rate, the bridge fills the difference with
repeated frames and the image judders.
Installing
Unzip anywhere and run OFXRBridgeTray.exe. It arms the bridge by itself.
Keep OFXRBridgeTray.exe and the ofxr folder together; it holds the OpenXR
layer, its settings and the Vulkan layer. If an earlier version is armed,
disarm it and close its tray first.
Tested
With a Pimax Crystal Super on an RTX 5090:
- DCS World (D3D11) on SteamVR and Virtual Desktop, through the menu and
into a mission - Assetto Corsa, SkyrimVR and Cyberpunk 2077 (D3D11) on SteamVR
- Hogwarts Legacy (UEVR, D3D12) with Cheeky Foveated DLSS on SteamVR and
PimaxXR, gaze driving the foveation - Microsoft Flight Simulator 2024 and The Callisto Protocol (UEVR),
unchanged
Please report results, working or not, on this fork's
GitHub Issues, with an OFXR flight log where you can. To
record one, enable Bridge flight recorder in the tray, reproduce the
problem, then use Open bridge logs. Logs are written under
%LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v334\.
OFXR Bridge v0.2.5 (V324)
An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.4.
What's new
- Vulkan support (experimental, off by default). Frame generation for
games that render through Vulkan. Tested with No Man's Sky through
OpenComposite on SteamVR. - Unity games no longer hang. Games whose D3D11 device is single-threaded,
which Unity creates by default, froze on the loading screen (The Forest VR
through OpenComposite was the reported case). They run now. - UEVR games with many swapchains now generate. Ghostwire: Tokyo showed a
red FPS number from the first frame because SteamVR ran out of swapchains.
The bridge now falls back to the lighter pipeline for that session instead
of giving up.
Vulkan support
Turn it on in the tray: Vulkan support (experimental). It is off by
default and will stay off by default until it has had more testing and
feedback — please report results, working or not.
What it does. With the option on, the bridge generates frames for Vulkan
games exactly as it does for D3D11 games: the game's frames are moved into
the bridge's own D3D12 device for optical flow and the generated frames are
moved back.
What it installs. A Vulkan game's runtime submits work on the game's own
GPU queue, and so does the bridge, from a second thread — which Vulkan
forbids, and which crashed the game after a few seconds in testing. So while
the bridge is armed with the option on, it registers a small Vulkan layer of
its own (OFXR_vulkan_queue_layer.dll) that puts a lock around queue
submissions. It does nothing else. It is registered when you arm and removed
when you disarm or close the tray, like the OpenXR layer itself, and the
watchdog removes it if the tray exits unexpectedly. Note that a Vulkan
implicit layer loads into every Vulkan application while it is
registered — browsers included. That is the reason the option is off by
default. If you ever need to keep the bridge armed but stop the layer for one
program, set OFXR_DISABLE_VULKAN_QUEUE_LAYER=1 in that program's
environment.
Known limitation: no FPS number in Vulkan games. The in-headset FPS
overlay has no Vulkan path yet, so the number does not draw and the
"delivered" counter with it. The purple and green diagnostic squares still
show that generation is running. Use fpsVR or the Virtual Desktop overlay to
read the rate.
SteamVR: turn off "fixed frame rate at half" for the game. In SteamVR's
per-application video settings, both this and Motion Smoothing make SteamVR
hold the game to half rate, and the bridge can then only deliver half. With
it off, No Man's Sky on a 72 Hz headset delivered a real 72.
Tested with: No Man's Sky (Steam) through the OpenComposite build linked
above, on SteamVR with a Pimax Crystal Super, through the menu, the galaxy
loading screen and into the world. Nothing else Vulkan has been tried yet.
Note that X-Plane 12, though it renders in Vulkan, submits to OpenXR through
a D3D11 bridge of its own and already worked before this release.
Other changes
- Games whose D3D11 device is single-threaded (Unity's default) never get a
second bridge thread, since that thread raced the game's on the device and
hung it. They run inline instead, which paces less well on SteamVR but does
not hang. Ticking nothing is needed. - When SteamVR refuses a swapchain while the bridge is arming with "Prefer
FPS over latency" (which needs four per eye against three), the session
drops to the lighter pipeline and arms again rather than passing the whole
game through. UEVR games that submit depth are the ones that hit the limit. - The headset's refresh rate is read from the compositor itself, so a game
that SteamVR throttles from its first frame no longer paces the bridge to
the throttled rate.
Known issues
- No FPS overlay in Vulkan games (above).
- Vulkan runs on SteamVR only in testing so far. VDXR has not been re-run
with the Vulkan layer; the earlier failure there was the same cause the
layer fixes, so it should hold, but it is unconfirmed. - Dips are often a resolution ceiling, not the bridge. Disarm the bridge
and play the same scene: if the dips remain, lower the per-eye resolution. - Pick a refresh rate close to double your game's frame rate. If double
is still short of the refresh rate, the bridge fills the difference with
repeated frames and the image judders. - Selecting the NVIDIA backend without an NVIDIA card silently does
nothing. On AMD or Intel, leave the backend on FidelityFX.
Installing
Unzip anywhere and run OFXRBridgeTray.exe. It arms the bridge by itself.
Keep OFXRBridgeTray.exe and the ofxr folder together — it holds the
OpenXR layer, its settings and, new in this release, the Vulkan layer. If an
earlier version is armed, disarm it and close its tray first.
Tested
On SteamVR with a Pimax Crystal Super OLED:
- No Man's Sky through OpenComposite (Vulkan, the option on)
- Ghostwire: Tokyo (UEVR, D3D12) — the swapchain fallback
- Microsoft Flight Simulator 2024 and Hogwarts Legacy (UEVR) — both
at 90 delivered on the deep pipeline, unchanged - The Forest VR through OpenComposite (Unity, D3D11) — the hang fix
- Assetto Corsa (D3D11) — unchanged
Please report results, working or not, on this fork's
GitHub Issues, with an OFXR flight log where you can. To
record one, enable Bridge flight recorder in the tray, reproduce the
problem, then use Open bridge logs. Logs are written under
%LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v324\.
OFXR Bridge v0.2.4 (V312)
An unofficial build on
tig3rmast3r's v0.2.1.
The first release after the 0.2.3 betas.
What's new
- Much better performance on SteamVR headsets (Pimax and any other headset
that runs through SteamVR). - The bridge arms itself when you start the tray.
- New option: Prefer FPS over latency. It is on by default. It adds one
frame of latency. In return, a game that only just reaches half your
headset's refresh rate can reach the full rate, and FPS dips are much
smoother.
If you saw little or no benefit on SteamVR before, try this release. The
likely cause is fixed. SteamVR was throwing away generated frames that were
already finished, so the frame rate barely rose even though the bridge was
working. How often that happened depended on the game and the machine, which
is why some users saw a clear gain and others saw almost none. The section
below explains what changed.
Much better performance on SteamVR
SteamVR needed work that other runtimes do not, and the bridge now has a
pipeline built specifically for it.
Why SteamVR needs it. The bridge sends the headset two frames for every
frame the game renders: the real one and a generated one. The two have to
arrive one display refresh apart. Virtual Desktop (VDXR) handles that itself:
each time the bridge asks for its next frame slot, it waits until one refresh
has passed. SteamVR answers straight away. If the bridge sent the second frame
then, both frames would arrive in the same refresh and the compositor would
throw one away. On SteamVR the bridge therefore has to time its frames against
SteamVR's compositor. It asks the compositor where it is in its current
refresh and places each frame in time for the next one.
What changed in this release. SteamVR only uses a frame once the GPU work
that produced it has finished, and it tracked that finish on the game's own
GPU queue. The game queues its next frame on the same queue straight away. So
a generated frame that was already finished could still look unfinished to
SteamVR, which dropped it and showed the previous image again. On SteamVR,
the bridge now gives the runtime a queue of its own, which holds only the
bridge's frames. The game's next frame can no longer delay them.
In our testing on a Pimax Crystal Super, Hogwarts Legacy at 8344×3268 held
87 FPS or more 94% of the time and felt steady at 90 throughout. In MSFS 2024,
the dips that used to stutter and freeze now stay close to 90.
The separate queue is used only for games that use D3D12 directly, and only
on SteamVR. On other runtimes it brought no gain, so they keep the game's
queue.
The bridge arms itself
Starting OFXRBridgeTray.exe now arms the bridge straight away; you no
longer need to pick Arm bridge until manual disarm first. As before,
closing the tray or selecting Disarm bridge turns it off. If arming
fails, the tray shows why and stays disarmed, and you can retry from the menu.
Prefer FPS over latency
A new tray option, on by default.
What it does. The bridge holds each generated frame back by one display
refresh, which gives the optical flow a whole refresh to finish its work.
Without the option, it has only the gap the game leaves between frames. When
the game is close to its limit, that gap is small, and generated frames that
finish late are dropped.
What you gain. If your game can only sustain half your headset's refresh
rate, you can now get the full benefit of frame generation. A game holding
45–50 FPS on a 90 Hz headset is likely to reach 90. Dips are also much
smoother, because a frame that is a little late no longer drops out.
What it costs. One frame of extra latency: about 11 ms at 90 Hz and
10 ms at 100 Hz.
When to turn it off. When your GPU has budget to spare. The simplest way
to tell is to try it: turn the option off and play the same scene. If you
still hold your full frame rate, leave it off and you save one frame of
latency. If you lose frames or the dips come back, turn it back on.
The change takes effect the next time the game starts.
Other changes
- D3D11 games drop fewer frames. For D3D11 games (Cyberpunk 2077 through
R.E.A.L. VR, Assetto Corsa and others), the bridge's own GPU work now runs at
high priority, as it already did for D3D12. In our Cyberpunk 2077 testing,
the frames SteamVR skipped fell from over 20 a minute to about 6. - Fewer missing generated frames in games that run their own frame
timing. MSFS 2024 sends frame timings that do not always move forward.
With Prefer FPS over latency on, the bridge now pairs frames in the order
the game renders them. Frames with an out-of-order timing still get a
generated frame instead of being skipped. - A generated frame is never shown unfinished. If the GPU has not finished
a generated frame by its turn, the bridge shows the previous frame again and
sends the generated one at the next refresh. - More detailed flight logs on SteamVR. With the Bridge flight recorder
on, the log now records every frame SteamVR's compositor settled, including
the ones it never showed. Reports with a log are much quicker to diagnose.
Known issues
- Dips are often a resolution ceiling, not the bridge. Disarm the bridge
and play the same scene: if the dips remain, your PC is past its comfortable
per-eye resolution. When you report a dip, please say whether it survives
disarming, and at what per-eye resolution. - Very high per-eye resolutions remain the hard limit. Above roughly 9
megapixels per eye, generated frames may not be finished early enough to be
shown. - Pick a refresh rate close to double your game's frame rate. Frame
generation doubles the game's frame rate. If double is still short of the
refresh rate, the bridge fills the difference with repeated frames and the
image judders. - If SteamVR is restarted while a game is running, the frame timing the
bridge reads from SteamVR may stop being accurate until the game is restarted. - Selecting the NVIDIA backend without an NVIDIA card silently does
nothing. On AMD or Intel, leave the backend on FidelityFX, the default.
Installing
Unzip anywhere and run OFXRBridgeTray.exe. It arms the bridge by itself.
Keep OFXRBridgeTray.exe and the ofxr folder together. If an earlier
version is armed, disarm it and close its tray first.
Tested
On SteamVR with a Pimax Crystal Super OLED:
- Hogwarts Legacy and The Callisto Protocol (UEVR, D3D12)
- Microsoft Flight Simulator 2024 (D3D12)
- Cyberpunk 2077 through R.E.A.L. VR (D3D11)
- Assetto Corsa (D3D11)
- Skyrim VR FUS with opencomposite (D3D11)
On a Quest 3 through Virtual Desktop (VDXR):
- Hogwarts Legacy and Microsoft Flight Simulator 2024, at 90, 100
and 144 Hz
Compatibility is not universal. Please report results, working or not, on
this fork's GitHub Issues, with an OFXR flight log where you
can. To record one, enable Bridge flight recorder in the tray, reproduce
the problem, then use Open bridge logs. Logs are written under
%LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v312\.
OFXR Bridge v0.2.3_beta5 (V278) — LR Real mod fix
An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.3_beta4 — one fix, nothing else changed.
Short version
If a game stopped starting on SteamVR since 0.2.3_beta3, take this build.
Cyberpunk 2077 through Luke Ross's R.E.A.L. VR mod was the reported case: with
the bridge armed before launch it never reached the menu.
If your games were starting fine, this changes nothing you can see. Frame
delivery, pacing, the overlay and every setting behave exactly as in
0.2.3_beta4.
If you had been working around this by arming the bridge after launching the
game, you no longer need to. Arm it before launch as usual.
What was wrong
0.2.3_beta3 fixed a crash in Assetto Corsa. The fix was to stop closing the
background connection the bridge opens to SteamVR to read the compositor's
delivered-frame counters — closing it is what killed the next VR session, so
since beta3 the connection is opened once and left open for as long as the game
runs. That part is correct and has not changed.
What it did not account for is that some VR mods start VR twice.
R.E.A.L. VR builds a short throwaway VR session at launch purely to ask the
headset what it is — field of view, resolution, which runtime is active — then
shuts the whole thing down and starts VR again for real. It does this on every
launch, on every runtime.
That throwaway session renders a single frame, and one frame was enough to make
the bridge open its connection to SteamVR. Because the connection is
deliberately never closed, it was still open when the mod started VR the second
time — and that second start never finished. The game was left waiting inside
SteamVR, with nothing to show for it.
It is also why arming the bridge after launching worked: that let the
throwaway session run with no bridge present, so nothing was left open when the
real session started.
The fix
The bridge now waits for the runtime to confirm that a session is actually being
displayed before it opens its connection. A throwaway session used only for
measurement never gets that far, so it never opens one, and the real start that
follows is unobstructed.
The Assetto Corsa fix is untouched — the connection still opens once and is
still never closed. It just no longer opens underneath a session that was only
ever going to be discarded.
Who this affected
SteamVR only, and only games or mods that shut VR down and start it again.
On VDXR, Oculus, PimaxXR and Virtual Desktop the bridge never opens this kind of
connection at all, so the fault could not occur there, and nothing about those
runtimes changes in this build.
If you use a R.E.A.L. VR mod — Cyberpunk 2077 and the other Luke Ross titles —
on SteamVR, this is the build you want. The same is true of anything else with
an in-game "restart VR" control.
Known issues
Unchanged from 0.2.3_beta4, which has the full list. The ones
most worth knowing:
- Dips are usually a resolution ceiling, not the bridge. Disarm the bridge
and play the same scene: if the dips are still there, your machine is past its
comfortable per-eye resolution. Dropping to about 0.92× removed nearly all of
them on the reporting machine. If you are reporting a dip, please say whether
it survives disarming and at what per-eye resolution — that one line saves the
most time. - Very high per-eye resolutions remain the hard limit. Above roughly 9
megapixels per eye the generated frame cannot be finished early enough to be
shown, and the bridge cannot tell that this is happening. - A very high headset refresh rate can outrun what generation can produce.
Generation doubles your game's frame rate; if double is still short of the
refresh rate the bridge fills the difference with repeats and it judders. Pick
a refresh rate close to double your game's frame rate. - If SteamVR is restarted while a game is running, the delivery counters may
stop being meaningful until the game is restarted. - Selecting the NVIDIA backend without an NVIDIA card silently does nothing.
On AMD or Intel leave the backend on FidelityFX, the shipped default.
Everything else is unchanged from 0.2.3_beta4
The SteamVR pacing work, the overlay's frame counter, the Assetto Corsa crash
fix, the D3D11 fix, the NVIDIA backend recommendation and every game-facing
setting behave exactly as described in the
0.2.3_beta4 notes.
Installing
Unzip anywhere and run OFXRBridgeTray.exe, then Arm bridge. Keep
OFXRBridgeTray.exe and the ofxr folder together. If you have an earlier
version armed, disarm it first.
Tested
- Cyberpunk 2077 through R.E.A.L. VR on SteamVR — the reported failure
to start, now fixed and confirmed by the reporter
on SteamVR with a Pimax Crystal Super OLED, on the NVIDIA OFA backend.
This is a targeted hotfix: one change, on the SteamVR-only path described above,
gated so that it cannot affect a session that reaches the headset. The rest of
the suite that ships with the source passes unchanged. The other titles listed
in the 0.2.3_beta4 notes were not re-run against this build.
This is an experimental beta and compatibility is not universal. Please report
results — working and not — on this fork's GitHub Issues, with
an OFXR flight log where you can. Enable one by setting logging_enabled=1
under [diagnostics] in ofxr_bridge.ini; logs are written next to the armed
layer under %LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v278\.
OFXR Bridge v0.2.3_beta4 (V277) — steadier delivery, and FPS counter fix
An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.3_beta3.
Short version
On SteamVR, more of the frames the bridge generates now actually reach the
headset. Measured on Hogwarts Legacy through UEVR — the title that has been
sitting below the others since beta1 — delivered frames went from about 77 to
about 84 a second, with stretches holding 89–90.
Nothing changed in how frames are generated, only in when they are handed
over. Image quality and every setting are untouched, and the pacing work is
SteamVR-only — VDXR, Oculus and PimaxXR hand frames over exactly as before.
The overlay's FPS number is also fixed — on Quest, Pico and anything else
that is not SteamVR it was counting frames that carried no new picture, and
could read your headset's refresh rate while the image was nothing like it.
If you still see dips, read the known issues. We now know what most of the
remaining ones are, and there is a one-minute test you can run yourself.
What was wrong
On SteamVR the bridge has to choose the moment to hand each frame to the
compositor. Miss the compositor's deadline and your frame is counted against the
next display refresh — which means two frames land on one refresh, the
compositor shows the first one twice, and the second is thrown away before it is
ever displayed.
Three separate mechanisms inside the bridge were all moving that moment, and
they were aimed at targets that did not agree with each other. Two of them
predate the current design and should have been retired when it arrived.
One was holding the schedule wherever the session happened to start. It had
no way to know whether that was a good place — it simply pinned the schedule
there. Across a 45-second capture it sat at its maximum correction on every
single evaluation, with an error it never once reduced, while pulling against
the mechanism that does know where the compositor's deadline is.
One was reading the compositor's clock at the wrong moment. It asked "how
long until your deadline?" before the bridge's own wait, then compared the
answer to a target describing the moment after it — about 9.9 ms apart, which
is very nearly a full display period. That mismatch did not show up as an
obvious ten milliseconds; it wrapped around into a small, plausible, wrong-signed
error. It spent 69% of frames pulling the schedule in the wrong direction.
The consequence was that the hand-over settled wherever those forces balanced,
rather than where SteamVR had asked for it — and whenever the game's load
shifted, the balance point moved and delivery followed it down.
Separately, the spacing between the generated frame and the real one could not
reach even. The controller that sets it was aiming at a band that made an even
spacing unreachable, so it always held some offset whether one was wanted or not.
The fix
The schedule now has one owner: the step that reads the compositor's clock at
the moment the frame actually goes out, and aims at the margin SteamVR asks for.
The other two stand down on SteamVR and are unchanged everywhere else. The pair
spacing controller can now settle at even, and does.
In numbers, on the same title and machine: the hand-over used to land with
3.3 ms of the compositor's frame remaining against a 2.5 ms target, and never
got there. It now lands at 2.50 ms — on target — and the correction that was
firing on 97–100% of frames now fires on 3–8%.
How to tell it is working
On SteamVR the overlay's figure should sit closer to your headset's refresh rate
and, more importantly, should stop wandering down over a session while every
other number looks fine. If you run fpsVR alongside, its frame-time graph should
look steadier between dips.
Also fixed: the overlay's FPS number
On runtimes other than SteamVR the counter was reporting submissions rather
than frames, and those are not the same thing.
When your game cannot produce enough frames to fill the headset's refresh rate
even after generation, the bridge hands the runtime the picture it already has
rather than leaving a gap — that is what keeps the image stable instead of
juddering. Those repeats were being counted. The result was a counter that could
read your headset's exact refresh rate no matter what was actually on screen.
Measured on The Witcher 3 at 144 Hz through Virtual Desktop: the overlay read
144 while the headset was receiving 78 distinct pictures a second, the other
66 being repeats. The number was wrong by nearly a factor of two, and it was
wrong in the most misleading direction — it looked perfect.
The counter now counts only frames that carry a new picture. On the run above it
would read 78.
On SteamVR you will see no change. There the figure is replaced by the
compositor's own count of what it actually displayed before it ever reaches the
overlay, so it was already telling the truth. This only ever affected runtimes
with no such source — Virtual Desktop, VDXR, Oculus, PimaxXR.
This makes the number honest, not the game faster. If it now reads lower
than it used to, that lower figure is what you were always getting.
Known issues
-
The remaining dips are a resolution ceiling, not the bridge. This is the
answer to the "Hogwarts sits at 81" item carried since beta2, and it is worth
a minute of your time:The test. Disarm the bridge and play the same scene. If the dips are still
there, they are not the bridge — your machine is past its comfortable per-eye
resolution, and no version of this tool will fix that. On the reporting machine
the dips appeared with the bridge disarmed whenever the game's own rate fell to
roughly 55 FPS or below.The lever is resolution. Dropping per-eye resolution to about 0.92× removed
almost all of them. Start there before changing anything else.If you use UEVR, its Synced Sequential rendering mode did noticeably
better than Native Stereo on the reporting machine. Worth trying. -
Very high per-eye resolutions remain the hard limit, unchanged. Above
roughly 9 megapixels per eye the generated frame cannot be finished early
enough to be shown, and the bridge cannot tell that this is happening — the
overlay will read the full rate while the headset does not. -
If SteamVR is restarted while a game is running, the delivery counters may
stop being meaningful until the game is restarted. Unchanged from beta3. -
The D3D11 fix from 0.2.3_beta2 is measured, not proven. The fault it
addresses is probabilistic, so a clean session does not demonstrate much. If a
D3D11 game still crashes inside the runtime, please report it. -
Selecting the NVIDIA backend without an NVIDIA card silently does nothing.
On AMD or Intel leave the backend on FidelityFX, the shipped default. -
A very high headset refresh rate can outrun what generation can produce.
Generation doubles your game's frame rate; if double is still short of the
refresh rate, the bridge fills the difference with repeats and the result
judders however good the pacing is. The Witcher 3 at 39 FPS into a 144 Hz
Quest 3 is 78 against 144, and it shows. Pick a headset refresh rate close to
double your game's frame rate — 72 Hz in that example — or lower settings
until the game can feed the one you want.
About the measurements in this note
The pacing figures come from one machine, one headset and one title —
Hogwarts Legacy through UEVR on SteamVR with a Pimax Crystal Super OLED. The
counter figures come from The Witcher 3 on a Quest 3 through Virtual Desktop.
Both faults are structural and not specific to those setups, but the size of the
difference on yours may vary. Reports either way are useful.
Everything else is unchanged from 0.2.3_beta3
The Assetto Corsa crash fix, the D3D11 fix, the NVIDIA backend recommendation,
the optical flow resolution setting and every game-facing setting behave exactly
as in 0.2.3_beta3. Non-SteamVR runtimes are not touched by any
of this.
Installing
Unzip anywhere and run OFXRBridgeTray.exe, then Arm bridge. Keep
OFXRBridgeTray.exe and the ofxr folder together. If you have an earlier
version armed, disarm it first.
Tested
- Hogwarts Legacy (UEVR) — the title this release is aimed at
- The Witcher 3 on a Quest 3 through Virtual Desktop at 144 Hz — where
the counter fault was found - The Callisto Protocol (UEVR)
- Skyrim VR through OpenComposite, with the FUS modlist
- Assetto Corsa — the beta3 crash fix, still fixed
on SteamVR with a Pimax Crystal Super OLED, on the NVIDIA OFA backend.
This is an experimental beta and compatibility is not universal. Please report
results — working and not — on this fork's GitHub Issues, with
an OFXR flight log where you can. Enable one by setting logging_enabled=1
under [diagnostics] in ofxr_bridge.ini; logs are written next to the armed
layer under %LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v277\.
If you are reporting a dip, please say whether it survives disarming the bridge,
and at what per-eye resolution — that one line saves the most time.
OFXR Bridge v0.2.3_beta3 (V271) — SteamVR / Assetto Corsa crash fix
An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.3_beta2 — one fix, nothing else changed.
Short version
If a game crashed at start-up on SteamVR since 0.2.3_beta1, take this build.
Assetto Corsa was the reported case: it crashed within a few seconds every time
on SteamVR, while working normally on VDXR. It now runs.
If nothing was crashing for you, this changes nothing you can see. Frame
delivery, pacing, the overlay and every setting behave exactly as in
0.2.3_beta2.
What was wrong
Since 0.2.3_beta1 the bridge opens a second, background connection to SteamVR
in order to read the compositor's own delivered-frame counters — that is what
made the overlay tell the truth and what the pacing is steered by.
That connection was opened and closed per OpenXR session. Most games create
one session and keep it, so the connection was opened once and closed at exit,
and nothing went wrong. Assetto Corsa creates and destroys its session three
times while starting up. It does that on every runtime, and it is perfectly
legal.
SteamVR ships its OpenXR runtime and its OpenVR client in the same binary,
vrclient_x64.dll. Opening our background connection into that binary and then
closing it left the next xrCreateSession through it reading a null
pointer, inside SteamVR's own runtime, with the bridge doing nothing but
forwarding the call.
Captured with a debugger: the fault is in vrclient_x64, and every session
created before our connection attached succeeded while the first one after
it died. In one run the connection attached three seconds later than usual and
the crash moved three seconds later with it.
The fix
The connection is now opened once per process and never closed. Sessions
after the first share it instead of opening their own, so there is no longer an
open-and-close cycle for a game's session churn to trip over.
Nothing else changed — the counters, the overlay, the pacing and the adaptive
margin all work exactly as before.
Who this affects
- Any title that recreates its OpenXR session while running, on SteamVR.
Assetto Corsa is the confirmed case; OpenVR-era titles reaching OpenXR
through a translation layer are the likely group. - Not VDXR, Oculus or PimaxXR — the bridge never opens this connection
outside SteamVR, which is exactly why Assetto Corsa always worked there. - Not single-session titles, which is almost everything else. For those the
only difference is that a connection which used to be closed at game exit is
now left for the process to take with it.
Known issues
- If SteamVR is restarted while a game is running, the bridge keeps its
original connection rather than making a new one, and the delivery counters
may stop being meaningful until the game is restarted. Restarting SteamVR
under a running game was never well supported; this makes it a little worse.
Report it if you hit it. - Hogwarts Legacy still sits around 81 rather than 89, unchanged from
0.2.3_beta2 and still under investigation. - The D3D11 fix from 0.2.3_beta2 is measured, not proven. The fault it
addresses is probabilistic, so a clean session does not demonstrate much. If
a D3D11 game still crashes inside the runtime, please report it. - Very high per-eye resolutions remain the hard limit, unchanged. Above
roughly 9 megapixels per eye the generated frame cannot be finished early
enough to be shown. - Selecting the NVIDIA backend without an NVIDIA card silently does nothing.
On AMD or Intel leave the backend on FidelityFX, the shipped default.
Everything else is unchanged from 0.2.3_beta2
The frame delivery work, the D3D11 fix, the NVIDIA backend recommendation, the
odd-looking frame times in fpsVR and the optical flow resolution setting are all
as described in the 0.2.3_beta2 notes.
Installing
Unzip anywhere and run OFXRBridgeTray.exe, then Arm bridge. Keep
OFXRBridgeTray.exe and the ofxr folder together. If you have an earlier
version armed, disarm it first.
Tested
- Assetto Corsa on SteamVR — the reported crash, now fixed
- Skyrim VR through OpenComposite, with the FUS modlist
- The Callisto Protocol and Hogwarts Legacy (UEVR)
on SteamVR with a Pimax Crystal Super OLED, on the NVIDIA OFA backend.
This is an experimental beta and compatibility is not universal. Please report
results — working and not — on this fork's GitHub Issues, with
an OFXR flight log where you can. Enable one by setting logging_enabled=1
under [diagnostics] in ofxr_bridge.ini; logs are written next to the armed
layer under %LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v271\.
OFXR Bridge v0.2.3_beta2 (V268) — SteamVR, Consistency, and a D3D11 fix
An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.3_beta1 — two fixes, no new features.
Short version
If you play a D3D11 game on SteamVR — Skyrim VR above all — take this build.
It fixes a fault that could crash or freeze the game, and it fixes frame
delivery in that title specifically.
Everyone else on SteamVR should take it too. 0.2.3_beta1's frame delivery
depended on where the bridge's schedule happened to start when you launched.
Sometimes that was a good place and you got the full rate; sometimes it wasn't,
and you lost a third of your frames for the whole session with no way back. That
is fixed. Same game, same machine, two launches now give you the same result.
Nothing outside SteamVR is touched. VDXR, Oculus and PimaxXR take exactly the
path they did in 0.2.3_beta1.
What was wrong
1. The schedule started wherever it landed, and stayed there
beta1 asks SteamVR where the display is and corrects towards it every frame.
That part worked. But the correction was limited to 50 microseconds a frame — a
size chosen for cancelling slow drift — while the error it had to fix could be
half a refresh interval. It never got there, so the session kept whatever
starting position it was given.
Worse, the arithmetic wrapped the error into one refresh interval. Being a
whole frame out looked identical to being perfectly on target, so the bridge
reported itself correct while your headset received half the frames. Nothing in
the bridge could see the difference.
Both are fixed: the correction is no longer limited to a size that cannot fix
the problem, and it no longer folds a whole-frame error down to nothing.
2. Two threads in the runtime at once, on D3D11 games
When the game uses D3D11 — Skyrim VR, and a number of older titles — the bridge
must keep its two threads from being inside the OpenXR runtime's D3D11 code at
the same time, because the NVIDIA driver does not survive it. That guard existed
but had a gap: one of the calls it needed to cover was never included.
Measured in a Skyrim VR session, the two threads met inside the runtime on
31.5% of calls — about 17,000 times in a single session. The NVIDIA D3D11
driver crashed twice in one afternoon of testing, and never once in 249 crash
logs going back eighteen months.
The gap is closed.
Measured
Delivered frames a second, from SteamVR's own counters, on a Pimax Crystal
Super OLED at 90 Hz:
| 0.2.3_beta1 | 0.2.3_beta2 | |
|---|---|---|
| Skyrim VR (D3D11, OpenComposite) | unplayable dips, crashes | 89.7 |
| The Callisto Protocol (UEVR) | varied by launch | 89.5 |
| Hogwarts Legacy (UEVR) | 67.7 | 81.4 |
Hogwarts and Callisto were measured back to back in the same areas. Skyrim VR
could not be measured meaningfully on beta1 because of fault 2.
How to tell it is working
The same signs as beta1 — the overlay counter should sit at your full refresh
while the game's own rate sits at half it, and fpsVR should agree.
What is new is that it should do so every launch, not some of them. If you
used to see one session run beautifully and the next one sit at two thirds for
no reason you could name, that was fault 1, and it is the thing this build is
for.
Known issues
- Hogwarts Legacy still sits below the others, around 81 rather than 89. It
is a large improvement over beta1's 67.7 but it is not where Callisto and
Skyrim are, and we do not yet know why — its submissions scatter more inside
the compositor's frame than other titles', despite the game itself being no
less steady. Under investigation. - The D3D11 fix is not proven, only measured. The fault it addresses is
probabilistic and can take a minute or more to appear, so a clean session does
not prove much. If a D3D11 game still crashes inside the runtime or freezes
with the process alive, please report it. - Very high per-eye resolutions remain the hard limit, unchanged. Above
roughly 9 megapixels per eye the generated frame cannot be finished early
enough to be shown. - Selecting the NVIDIA backend without an NVIDIA card silently does nothing.
On AMD or Intel leave the backend on FidelityFX, the shipped default.
Everything else is unchanged from 0.2.3_beta1
The NVIDIA backend recommendation, the odd-looking frame times in fpsVR, the
optical flow resolution setting and the installation steps are all as described
in the 0.2.3_beta1 notes. Nothing in this release changes how
frames are generated — only when they are handed over.
Installing
Unzip anywhere and run OFXRBridgeTray.exe, then Arm bridge. Keep
OFXRBridgeTray.exe and the ofxr folder together. If you have an earlier
version armed, disarm it first.
Tested
- Skyrim VR through OpenComposite, with the FUS modlist
- The Callisto Protocol and Hogwarts Legacy (UEVR)
- Microsoft Flight Simulator 2024
on SteamVR with a Pimax Crystal Super OLED, on the NVIDIA OFA backend, and
cross-checked on a Quest 3 through VDXR with no change to that path.
This is an experimental beta and compatibility is not universal. Please report
results — working and not — on this fork's GitHub Issues, with
an OFXR flight log where you can. Enable one by setting logging_enabled=1
under [diagnostics] in ofxr_bridge.ini; logs are written next to the armed
layer under %LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v268\.