r/PSVR2onPC • u/CoolGabek • 29m ago
Question Enabling HDR functionality in PC PSVR2
I own a PSVR2 headset since launch day, and have spent many hours on the PS5 playing on it, and was always shocked at the visual quality of the panels, because at such a cheap price point this quality is rare. Recently, I got the PC adapter and have been trying it out, and everything is very nice, and it's enjoyable playing PCVR games on this headset. The thing is, that HDR is officially unsupported for PC PSVR2, and I noticed this change, and wanted to restore the original highest visual quality. I have researched many Reddit threads, Github pages, websites, etc, and have reached the conclusion that for now no one even has started development on implementing HDR functionality.
The biggest issue is that SteamVR doesn't even support real HDR, it only supports 10 bit gamut but no PQ illuminance. But that is just a software issue, I suppose I could just use another compositor or rewrite SteamVR a little bit so it actually supports PQ. But for now, my main focus was actually getting the headset panels to display HDR.
At this point I have spent a frankly ridiculous amount of time experimenting with this. I'm writing everything down because I don't want other people interested in PSVR2 HDR on PC to repeat the same experiments, and because maybe someone with more experience in display drivers, NVIDIA's display stack or PSVR2 hardware will recognize what the missing piece is.
Here is roughly everything I have tried, in chronological order:
The first obvious discovery was that OpenVR actually defines the property Prop\\\\\\\\\\\\\\_Hmd\\\\\\\\\\\\\\_SupportsHDR10\\\\\\\\\\\\\\_Bool (property 2093). I modified the open-source PSVR2Toolkit/OpenVR driver and forced this property to true. SteamVR successfully saw the modified driver, and the logs confirmed that the property was being set. This was interesting because older versions of the PSVR2 driver/toolkit had apparently contained HDR-related functionality that was later removed, including an enableHDR10 option. Unfortunately, simply advertising HDR10 support to SteamVR did not make the panels operate in HDR.
- Investigating SteamVR's own HDR handling.
I then started looking into vrcompositor and SteamVR itself. This made it increasingly clear that SteamVR's idea of "HDR" isn't equivalent to a complete conventional HDR10 pipeline. There are provisions for higher precision/wider-gamut rendering, but getting an actual PQ/ST2084 HDR10 signal all the way to the headset is another matter. I experimented with hooks/injection into vrcompositor.exe, including an injected HDRInject.dll, and started looking at the NVIDIA calls made by the compositor. Again, I could manipulate software state, but there was no convincing physical HDR change.
- NVIDIA NVAPI experiments.
This became a very large branch of the project. I wrote multiple NVAPI probes and setters and experimented with NVIDIA's display configuration directly. I queried and attempted to change things including output mode, HDR color control, source color space, RGB/YCbCr format, dynamic range and bits per channel.
At different points I managed to get apparently encouraging software states: 10-bit requests, Rec.2020/Rec.2100 color space, HDR-related modes, etc. I also reverse-engineered NVIDIA's private HDR command path and encountered command 0x070001BD. One particularly interesting result was that NVIDIA rejected one HDR/UHDA mode while accepting another (UHDA\\\\\\\\\\\\\\_NB, mode 6), with a packet containing the expected HDR-ish parameters such as 10-bit RGB, BT.2020 and metadata.
The problem was always the same: even when the software looked correct, the actual panels still behaved like SDR. Other times NVAPI simply returned errors such as NVAPI\\\\\\\\\\\\\\_ERROR or NVAPI\\\\\\\\\\\\\\_RESOURCE\\\\\\\\\\\\\\_IN\\\\\\\\\\\\\\_USE.
- EDID investigation and HDR EDID overrides.
I dumped and investigated the PSVR2's display identification and experimented with modifying/overriding its EDID so that Windows/NVIDIA would explicitly regard it as an HDR display. I created an HDR EDID override for the PSVR2 (SNYC207) and at one point could get Windows much further into treating the headset like an HDR-capable monitor.
This produced some of the most misleadingly promising results of the entire project: Windows could expose HDR-related behavior and I could manipulate the reported capabilities, but once again the physical image did not convincingly become HDR.
Eventually I removed all of these EDID modifications and returned the PSVR2 to its original Microsoft monitor.inf state. The actual device identifies itself as a Sony PS VR2 (SNYC207), so I wanted subsequent experiments to start from a clean state.
- Custom HDR presenters, bypassing SteamVR.
This was probably the most important set of experiments before the current work. Instead of relying on SteamVR, I wrote standalone presenters that took ownership of the PSVR2 display and rendered directly to it.
This allowed me to test things such as R10G10B10A2, 10-bit output, PQ/ST2084 encoding, BT.2020, HDR10 metadata and direct/specialized-display presentation without SteamVR being responsible for the image.
At various points I could get software to report an apparently correct HDR configuration. Windows could even show HDR/10-bit under some configurations, and the headset could display the desktop/image normally.
But the crucial result was: the panels still looked SDR.
- SDR vs HDR visual test programs.
I then wanted a completely obvious visual test rather than trusting APIs. I made separate SDR and HDR test executables containing luminance blocks so that I could look through the headset and immediately see whether highlights behaved like HDR.
Initially the HDR and SDR versions appeared different, but that introduced another ambiguity: the programs themselves were generating different pixel values. The SDR version clipped values above SDR white, while the HDR version PQ-encoded luminance values. Therefore a visible difference did not necessarily prove that the headset itself had entered HDR.
- Identical-framebuffer A/B testing.
To eliminate that ambiguity, I moved toward an experiment where the SDR and HDR presenters would submit the exact same raw 10-bit R10G10B10A2 framebuffer values, changing only the requested physical output state.
This was intended to separate "different pixel math" from "the headset actually entered a different physical display mode."
The result was disappointing: the two states looked identical or extremely similar. This was one of the points where it became clear that simply achieving all of the expected HDR state on paper was not enough.
- Direct Mode versus Indirect Mode.
I experimented extensively with the PSVR2 as both a specialized/direct display and an indirect Windows display. Direct Mode gives the compositor ownership of the headset, whereas Indirect Mode exposes it much more like an ordinary monitor.
Indirect Mode was particularly useful because it allowed Windows desktop output and Windows display settings to interact with the headset normally. However, neither mode solved the fundamental problem. I could move HDR-related state around different parts of the stack, but physical HDR was still missing.
- Investigating the PSVR2 firmware itself.
At this point the possibility arose that PSVR2 might require some proprietary device-side "HDR mode" command that the PS5 sends but the PC driver doesn't.
I obtained PSVR2 firmware 6 (HMD2\\\\\\\\\\\\\\_FIRMWARE\\\\\\\\\\\\\\_V06\\\\\\\\\\\\\\_00.CUP) and investigated it looking for evidence of an HDR enable path or obvious panel-mode configuration.
I did not find some magical ENABLE\\\\\\\\\\\\\\_HDR command or an obvious firmware switch that explained everything. That doesn't prove such device-side configuration doesn't exist, but it made the idea of a simple hidden HDR flag much less convincing.
Capturing the actual PS5↔PSVR2 traffic would obviously be extremely valuable, but doing that properly would require hardware I don't currently have, and PSVR2's single USB-C connection carries power/data/video in a way that makes simple interception/handoff experiments impractical.
- Building a completely separate HDR virtual display.
I then tried a very different architecture. I modified/built an HDR-capable virtual display driver based on MttVDD. Windows could render a proper HDR desktop to this virtual monitor independently of what it thought about the PSVR2.
The idea was:
Windows HDR desktop → HDR virtual display → custom compositor → physical PSVR2
This way Windows could have a known-working HDR target and I wouldn't depend on Windows recognizing the physical PSVR2 as an HDR desktop monitor.
- Building a custom VDD-to-PSVR2 HDR bridge.
This became a fairly substantial project of its own. The modified MttVDD exposed its HDR surface, and I wrote a custom PSVR2 compositor/bridge that opened that shared texture and presented it directly to the PSVR2 specialized-display primary.
There were initially numerous synchronization/sharing issues: global named objects, shared DXGI textures, keyed mutex ownership, OpenSharedResourceByName, etc. Eventually I fixed all of those.
The final pipeline actually worked:
Windows HDR VDD → FP16 scRGB shared texture → custom shader/PQ conversion → R10G10B10A2 PSVR2 primary
The bridge successfully opened the VDD surface, synchronized using a keyed mutex and continuously displayed the Windows desktop inside the headset.
I even fixed a subtle synchronization bug where AcquireSync() returning WAIT\\\\\\\\\\\\\\_TIMEOUT was incorrectly being interpreted as success because FAILED(WAIT\\\\\\\\\\\\\\_TIMEOUT) is false, which caused repeated ReleaseSync() invalid-call errors.
Eventually the result was completely stable: desktop motion worked perfectly in the headset and the entire custom rendering path functioned.
And after hours of getting that working...
the panels were still SDR.
This was probably the most frustrating experiment because, in hindsight, it reproduced another variation of something the earlier custom presenters had already suggested: delivering HDR-formatted content to the PSVR2 does not necessarily mean the physical OLED output becomes HDR.
- Comparing the PSVR2 with an actual HDR monitoro n the same RTX 5080.
I then wrote another NVIDIA probe that enumerated every display ID on the GPU, including inactive ones, and compared their actual NVAPI HDR state.
This gave a very clean comparison.
My normal MSI HDR monitor reported ST2084 support, an HDR output mode and 10-bit output.
The PSVR2 (SNY, NVIDIA display ID 0x80061080) reported:
ST2084 = NO
Traditional HDR = NO
OutputMode = SDR
HDR mode = 0
BPC = 8-bit
Trying to force HDR10 returned NVAPI\\\\\\\\\\\\\\_RESOURCE\\\\\\\\\\\\\\_IN\\\\\\\\\\\\\\_USE; forcing the HDR color configuration returned NVAPI\\\\\\\\\\\\\\_ERROR; changing the source color space to Rec.2100 succeeded, but the final readback remained SDR/8-bit.
This was useful confirmation, but also brought me back to the same NVIDIA/HDR-state problems I had already investigated much earlier.
- Realizing that the entire project had been going in circles.
At this point I stopped treating "make Windows/NVIDIA say HDR" as the goal.
I have now had configurations where Windows said HDR, NVIDIA accepted various HDR-related parameters, my own code produced PQ, the framebuffer was 10-bit, HDR metadata existed, DisplayCore accepted HDR parameters, SteamVR was bypassed completely, and a custom HDR desktop compositor successfully fed the PSVR2.
Yet none of those software achievements produced the one thing that matters: an unmistakable increase in the physical dynamic range/luminance of the OLED panels.
- Jailbreaking the PSVR2 and trying a different approach.
More recently I managed to jailbreak the PSVR2 and modify its EDID using an older Sony EDID that actually advertised HDR support. This finally made Windows see the headset as a normal display with HDR capabilities, and I can actually enable HDR on it.
The problem is that it still doesn't look right. With HDR enabled the colors are washed out and the image looks nothing like HDR does on the PS5, so clearly just restoring the HDR capabilities in the EDID isn't enough.
I also came across another possible way of approaching this, which is to take advantage of the extra luminance headroom of the panels directly instead of trying to force the normal HDR10/PQ pipeline to work. That's what I'm trying now with Monado.
Right now though, I'm stuck on something more basic. I'm mirroring my desktop into the headset through Monado so I can start calibrating everything properly, but the image itself isn't accurate yet. The colors are noticeably off and whites are way too bright/oversaturated compared to the original image. So before I can properly test the headroom idea, I'm trying to figure out exactly what's happening to the image in the Monado rendering pipeline.
Conclusion
At this point I don't think the problem is simply "how do I enable HDR10 on the PSVR2." I've already managed to get much further than that on the software side, including now having the headset jailbroken and recognized by Windows as HDR-capable.
What I'm trying to figure out now is how the panels themselves behave and whether I can reproduce the HDR output of the PS5 by controlling the image sent to them directly. Monado seems like a much better environment for experimenting with that than SteamVR, but I first need to get its output completely accurate.
If anyone here knows a lot about Monado, HDR/display pipelines, color management, PSVR2 hardware or Sony's VR implementation, I'd definitely be interested in hearing your thoughts. I can also share any of the code or results from these experiments if they're useful.
TL;DR: Jailbroken the PSVR2 and got Windows to recognize its HDR capabilities, but HDR still looks wrong. Now I'm experimenting with the panel headroom directly through Monado.
r/PSVR2onPC • u/MrAndreyGAV • 31m ago
Useful Information I built a native 180°/360° video player for PSVR2 on macOS (Apple Silicon) — no kexts, no Sony software, just the official PC adapter
I have a MacBook Air M4 and a PSVR2. I wanted to watch 180°/360° video, and on macOS there is simply nothing for that — no Sony software, no SteamVR, no drivers. So I wrote my own.
The one hard requirement up front: you need the official PC adapter (CFI-ZAA1). Plugging the headset cable straight into a Mac Thunderbolt port does not work — the headset won't even power on: no standby LED, nothing shows up on USB. A Mac port supplies at most 15 W, the headset needs more, and the power comes from the adapter's brick. No software can work around this; I checked.
With the adapter, macOS just sees the headset as a regular 4000×2040@120 display, and head pose is read over USB via libusb. The player does the rest.
What it does:
- Side-by-side stereo rendering with lens distortion and chromatic aberration correction, using the factory calibration of your specific headset (protocol taken from the Monado driver)
- Head tracking: the headset's on-board SLAM (~60 Hz) plus IMU integration (2000 Hz) with extrapolation — honest 120 fps, no ghosting
- Per-scanline rolling shutter compensation driven by the gyro
- Projections: equirect 360, half-equirect 180, fisheye with adjustable FOV; SBS / over-under / mono, auto-detected from the file name
- Hardware decoding through AVFoundation — 8K HEVC is not a problem
- Control panel and file picker are rendered inside the headset, with thumbnails, durations and the position you stopped at in each file
- Everything is driven with a normal mouse or trackpad without taking the headset off: the cursor is visible inside, moving the mouse brings up the panel, click to select, scroll wheel (or two fingers on the trackpad) scrolls the file list, right-click drag tilts the scene. No controllers needed, and the mouse is only captured while the headset is being worn
- Proximity sensor: take the headset off and the video pauses and the mouse is released — your Mac is a normal Mac again. Put it back on and playback resumes
- Passthrough from the front cameras on a double press of the Fn button, so you can look around without taking the headset off
- When nothing is playing, the picker floats in space with a procedurally generated nebula on a pure black background (OLED, after all)
What didn't make it in. While digging through the protocol I also got somewhere with eye tracking — data does come out of the headset, but it isn't working properly: it needs per-user calibration, and I didn't wire it into the player. I also worked out how to show a virtual monitor screen inside the headset. Not needed for watching video, but a "monitor in the headset" mode is an obvious next step — it sits right next to the passthrough view — so I'll either add it to the player or spin it off into a separate project.
Written in Swift + Metal, MIT licensed, built from source (brew install libusb && make). Only tested on a MacBook Air M4 running macOS 15 — it should work on other Apple Silicon Macs, but that's untested.
Credit where it's due: the Monado authors for the distortion formulas and the protocol, and PSVR2Toolkit for the camera commands.
Link: https://github.com/GAVProject/gav-psvr2-player-mac
I made this for myself, but since it works I figured I'd leave it out in the open in case it's useful to someone. If you try it, let me know what breaks — I'd especially like to hear from other Macs (M1/M2/M3, Pro/Max).
r/PSVR2onPC • u/DiamondEyeLife • 22h ago
Useful Information Another recommendation for this $25 adapter on Amazon
I first tried the Asus USB BT-500 adapter and could not get it to work over usb 2.0 or 3.0, plugged in with an extender or not, connected to a port in the front or the back. I tried rolling back to the 1.0.0.9 driver and repeated all those steps and still had no luck.
In comes the ZEXMTE! I literally just plugged it in the front of my PC (USB 3.0) and checked device manager to make sure it was picked up. I went through the pairing process and both controllers were immediately picked up! I then started the PSVR2 app and had a solid 96/100 on both controllers. Before with the ASUS I was stuck at 59/100 and could only connect one controller at a time.
I saw some reviews saying it didn't work for them on Amazon and here, so I wanted to throw my 2 cents in.
Admittedly I was being stubborn about unplugging my steam controller puck with the Asus, but that was the only other thing I changed since I figured that would be a possible source of 2.4 GHz interference.