Skip to content

Releases: JMS1717/Quest3-Pyrowave

alpha.9: 207 Hz at full resolution, a faster decoder, 144-240 Hz, Wi-Fi

Choose a tag to compare

@JMS1717 JMS1717 released this 07 Oct 17:01

alpha.9: 207 Hz at full resolution, a faster decoder, 144-240 Hz

This prerelease packages the .63 stack:

  • PRs #10-#12, #13 (multilevel Haar), #14 (Decoder V2, packed YCbCr output) and #15 (parallel
    wired video, frame trace).
  • Four fixes found in review or in Wi-Fi testing.
  • The first measured Wi-Fi results.

Highlights:

  • Haar GPU decode at 207 Hz takes about half as long as before: 2.6-2.8 ms, down from 5.6 ms.
  • At the owner's settings the client shows about 195 fresh frames per second at 207 Hz with
    2080x2208 per eye
    in 10-12 s screens. The .55 build managed about 117 there.
  • Wi-Fi 6E carries the same 207 Hz stream at 1000 Mbit/s with 189-195 fresh FPS. It adds about
    3.4 ms of network time against USB (WIRELESS.md).

Keep alpha.8 for rollback. Not established: sustained gameplay, optical motion-to-photon latency,
and an advantage over Virtual Desktop.

Changes since alpha.8

Faster decoding on the Quest

Multilevel Haar (HAAR32.md).

  • Two dispatches per plane instead of one per level.
  • Levels 0-1 are stored as packed quads, and luma as a half-size RGBA8 plane.
  • Haar decode at 4160x2208 drops from 4.7 to 3.0 ms.

Packed YCbCr straight into the eye-copy buffer (mode 5, default)
(PRESENT-YCBCR.md).

  • The decoder writes luma and chroma into the hardware buffer the eye pass reads.
  • The eye shader converts to RGB, so the separate full-frame conversion pass is gone.
  • The client falls back to the previous mode where the buffer cannot be written as a storage
    image.

Decoder V2 for CDF 5/3 (DECODER-V2.md).

  • A register-only inverse 5/3 with the same packed output.
  • It is about 3x faster than the stock 5/3 decoder: 2.3 against 7.9 ms on the bench, and 4.1
    against 11.4 ms live at 207 Hz.
  • CDF 5/3 removes Haar's 8-pixel block edges and looks much smoother in the headset. It costs
    fresh frames: about 2 FPS at 700 Mbit/s with the maximum GPU clock, more at higher bitrates.
  • Haar stays the default wavelet.

Cheaper eye copy (FRAME-TRACE.md).

  • On an sRGB swapchain the eye pass now writes the already sRGB-coded values with sRGB encoding
    turned off.
  • That saves about 0.2 ms per frame with an identical image.

Refresh rates and profiles

Any whole refresh rate from 144 to 240 Hz (PRs #10 and #12).

  • Rates up to 207 Hz run on the native panel mode; 240 Hz uses the scaled panel mode.
  • Over USB the PC switches the Quest 3 panel itself, and restores it when SteamVR stops.

Measured streaming profiles in Settings, Presets, Streaming profile:

Profile Stream per eye Fresh FPS (short screens)
Native 120 Hz 2064x2208 about 119
207 Hz (updated) 2080x2208 (was 1440x1536) about 195
240 Hz scaled panel 1440x1536 about 223-228
  • The 207 and 240 Hz profiles also turn on the maximum GPU clock (690 MHz) over USB.
  • The 120 and 240 Hz rows were measured before the new decoder.

Bitrate, quality and transport

  • Bitrate: sliders go up to 4000 Mbit/s, the USB 3.2 Gen 1 payload ceiling.
    • A quality floor keeps PyroWave at 0.25 bits per stream pixel or more.
    • Encoder rate allocation is weighted for the headset's pixels per degree
      (ENCODER-CSF.md, BITRATE.md).
  • Two parallel wired video connections by default
    (video.pyrowave.wired_video_connections, 0-4).
    • Over USB each frame is split across dedicated adb-forwarded connections.
    • That cuts ALVR's network-stage estimate by 0.7 ms at 1000 Mbit/s and 1.8 ms at 1500.
    • If the client does not answer on every port, video stays on the stream socket.
  • Optional: an adaptive Lanczos-3 render downsample filter, light foveated encoding
    (LIGHT-FOVEATION.md), and 4:4:4 chroma (CHROMA.md). All are
    off by default.

Wi-Fi and connection fixes (.63)

  • Wired mode chooses a USB headset only.
    • It uses an online adb device attached over USB. Before, the headset's own Wi-Fi adb address
      could be taken for a wired device and the stream tunnelled through adb.
    • An offline or unauthorized USB entry no longer blocks connecting.
    • When the wired connection isn't ready, the server goes on to manual IPs and discovery. Before,
      the wired entry stopped it from ever trying the network.
  • Auto bitrate respects network latency. The quality floor raises Auto's estimate, but the
    network-latency and maximum limits still apply. Under congestion Auto can go below the floor
    instead of queuing frames.
  • No mixed frames on parallel wired connections. A frame whose timestamp repeats the previous
    one (a game stutter re-presenting a pose) is skipped. Before, its slices could mix with the first
    copy's.
  • Packed YCbCr fallback.
    • If the eye copy's packed-YCbCr programs fail to build on a driver, packed frames go through the
      staging path, which converts them. Before, they were drawn with wrong colours.
    • The staging renderer logs a failure of its own packed program instead of stopping the client.

Wi-Fi measurements, 207 Hz, 2080x2208, Haar, Wi-Fi 6E at 6 GHz with the PC on Ethernet
(WIRELESS.md):

Bitrate Fresh FPS ALVR network p50 / p99
1000 Mbit/s 189-195 6.1 / 10-13 ms
1250 Mbit/s 190-192 7.1 / 21-49 ms
1500 Mbit/s frames about 380 ms late the link's limit was exceeded
Auto (max 1500, 8 ms limit) 197-200 4.4 ms; settles at about 550 Mbit/s

On Wi-Fi:

  • Use a constant 1000 Mbit/s (1250 at most), or Auto with a maximum and the latency limit.
  • The server's GPU-clock and panel helper works only over USB.

Usability and fixes

  • Stream-start settings apply by themselves. Refresh, resolution, wavelet and similar settings
    changed while streaming reconnect after 2 s, restarting SteamVR when needed
    (SETTINGS-APPLY.md).
  • Display helper.
    • HorizonOS writes debug.oculus.refreshRate=72 itself when a VR app starts with the property
      empty. The server no longer undoes that write, which had restarted the client every few
      seconds.
    • The server now logs when client statistics stop.
  • Overlay modes, independent game and stream controls, and diagnostics (PR #9).

For developers

  • Diagnostics: an opt-in per-frame critical-path trace (debug.q3pw.frame_trace=1) and its
    analyzer (tools/quest3/frame_trace.py).
  • Opt-in experiments, not defaults: debug.q3pw.release_fd=1 and
    debug.q3pw.frame_hold_us. Results are in FRAME-TRACE.md.
  • Local fast builds: LOCAL-BUILD.md.

Defaults

Fresh installs keep the conservative 400 Mbit/s / 72 Hz candidate. The other defaults:

  • Haar wavelet, 4:2:0, TCP, Quest 3 Auto (Compute decoding).
  • Packed YCbCr output, two wired video connections.
  • No foveation.

Saved settings are preserved. To try high refresh, choose Quest 3 PyroWave 207 Hz (measured)
in Settings, Presets, Streaming profile, with the headset connected over USB (or over Wi-Fi
at 1000 Mbit/s, without the GPU-clock helper).

To install:

  1. Stop SteamVR.
  2. Extract the new server into a separate folder and run its dashboard.
  3. Install the matching APK.
  4. On the Quest, open Quest3 PyroWave from Unknown Sources, then trust the headset and register
    this server.

Keep the previous pair.

Known issues

  • Not hardware-tested in this build:
    • The USB wired path. USB adb was offline during .63 testing, and every run in this build was
      over Wi-Fi. Wired streaming was last measured on .62, and the .63 device choice is covered
      by unit tests.
    • The duplicate-frame skip and the packed-YCbCr fallback, since no stutter or driver failure was
      available to trigger them.
  • Unplugging and replugging USB with two wired video connections hasn't been checked. If video
    stops, set Wired video connections to 0.
  • The "207 Hz (measured)" profile name refers to 10-12 s screens. Sustained play at that profile
    is not yet measured.
  • Constant bitrate above the Wi-Fi link's capacity queues frames without limit (about 380 ms at
    1500 Mbit/s on the test link). Stay at or below about 1250 Mbit/s on Wi-Fi, or use Auto.

Not in this release

  • No claim of sustained 207 fresh FPS, optical latency or perceptual parity with Virtual Desktop.
  • Frame hold, release fence, mode 6 and the eye diagnostics stay opt-in or diagnostic only.
  • Rejected work stays out: fused colour, levels 4-2 fusion, Haar H2.

Build

  • Source commit: 51445ea (the tag points at it).
  • Protocol: 20.13.0-quest3.pyro.63. Use the APK and the Windows server from this release together.
  • Built locally from a clean tree with the pinned toolchain (LOCAL-BUILD.md), not by CI. BUILD-METADATA.json lists the inputs, checks and hashes.
  • Signed with...
Read more

Quest 3 pacing, resolution controls and safety preview

Choose a tag to compare

@JMS1717 JMS1717 released this 05 Oct 15:46

alpha.8: native-frame pacing, usability and safety

This prerelease packages the reviewed .51 integration. Retain alpha.7 for
rollback. It improves usability, pacing and safety; sustained 120 fresh FPS and
an advantage over Virtual Desktop remain unproven.

Changes since alpha.7

  • Bounded fresh-frame selection: the default waits up to half a frame while a
    decode is active (4 ms at 120 Hz). Interleaved Quest screens recorded roughly
    4–8 more distinct target frames/s than no wait. See
    freshness evidence.
  • Automatic LOW decode queue priority for 4:2:0 at <=120 Hz when supported,
    with a default-priority fallback. Measured 120 Hz screens improved target
    delivery and reduced eye-copy stalls; the policy avoids applying that rule
    at 144 Hz, where LOW regressed delivery. See
    priority evidence.
  • Independent SteamVR source and encoded sizes. Request 3072 x 3216 per eye
    (aligned to 3072 x 3232) on PC while retaining 2080 x 2208 Quest decode.
    Actual game render size still depends on SteamVR/game settings. See
    resolution controls.
  • Later native-buffer lifetime, descriptor-ownership and Rust unwind cleanup
    fixes; production publication race tests and bounded diagnostic tooling.
  • Clearer USB verification, bitrate math, Auto bitrate guidance, overlay override
    troubleshooting, OpenXR game-launch help and rollback documentation.
  • Updated README, engineering handoff and sanitized, reproducible findings.

Default behavior and recommended comparisons

Fresh-install defaults remain the 400 Mbps /72 Hz conservative candidate,
4:2:0, TCP, full-frame encoding and Quest 3 Auto -> Compute. Existing saved
settings are preserved; installing a new build does not reset them to this
candidate. This starting profile is not universally live-validated.

The screened experimental recipe is 2080 x 2208 per eye, confirmed 120 Hz,
1000 Mbps, Haar/Compute, 4:2:0, no foveated encoding, USB/TCP and one worker.
Direct eye copying remains an explicit opt-in. The normal decode path is
synchronous. Start from matching binaries and follow the existing
setup guide
and USB guide.

To install, stop SteamVR, extract the new server into a separate folder and run
its dashboard. Install the matching APK, open Quest3 PyroWave from Unknown
Sources, trust the headset and register this server. Keep the previous pair.
The overlay starts enabled; click both thumbsticks together, release both, then
click again to toggle. An old forced-visible benchmark override must be cleared
as described in the overlay guide.

For the optional native-resolution direct-eye comparison, explicitly enable the
path on your connected Quest and reopen the app after these commands:

adb shell setprop debug.q3pw.decode_workers 1
adb shell setprop debug.q3pw.direct_eye_copy 1
adb shell am force-stop io.github.jms1717.quest3pyrowave

Use SDR, matching encoded/output eye sizes, no client upscaling or foveation and
no passthrough for this baseline. Larger PC source rendering can remain separate.
Verify actual direct-copy counters rather than assuming the property activated
the path. To return to staging, set debug.q3pw.direct_eye_copy to 0 and reopen
the app. Restore any other manually changed debug properties to their original
values; an APK update does not clear existing research overrides.

Publication notifications, prerecording, experimental ready/release fences,
asynchronous eye-copy completion and Surface presentation remain off by default.
Keep stage probes off for ordinary play. Light foveated encoding and 4:4:4 are
optional quality experiments, not new release defaults. Do not set 2000 Mbps
by default: recorded extra payload did not establish better delivery or latency.

Explicit exclusions

  • Haar H2 (debug.q3pw.haar_h2) is excluded due to the R16F/R8 shader/view defect.
  • Final-color fusion (debug.q3pw.fuse_color) is excluded from this .51 pair.
    Its branch is preserved separately for exact-pixel and setting-lifetime tests.
  • No promotion of the rejected 6 ms selection wait or other neutral experiments.
  • No 207/240 Hz, high-resolution or 15–20 ms motion-to-photon performance promise.
  • No automatic installation, SteamVR/driver switch, headset recovery override,
    thermal override or system/network change.

What the evidence supports

Later short native120 controls delivered approximately 117 distinct targets/s,
while the general client FPS counter was around120. A .50 stationary window
reported GPU decode p50 5.90 ms, conversion p50 0.77 ms and native fence p50
7.98 ms. These are different intervals, not additive latency components.
Earlier pacing screens still had p1 near60. See the
whole-stack scorecard.

The alpha.7 direct-copy screens were around104 fresh submissions/s. Those and
later117/s captures differ in session, clocks and conditions; do not advertise
that cross-version difference as a controlled percentage gain. The bounded-wait
and priority comparisons above are the relevant controlled evidence.

Sustained fresh120, broad game compatibility, continuous pose/image acceptance,
thermal endurance, optical FPS and motion-to-photon latency remain unmet or
unverified. Screenshot/GPU readback checks do not replace human in-headset quality
acceptance. No latency or image-quality superiority over Virtual Desktop is proven.

Release assets

  1. Quest3-Pyrowave-dev.apk — stable-signed main build, protocol .51.
  2. Quest3-Pyrowave-Windows.zip — matching server/dashboard, with notices.
  3. Quest3-Pyrowave-Android-LICENSES.zip — Android dependency notices.
  4. APK-CERTIFICATE.txt — public signing fingerprint, matching alpha.7.
  5. BUILD-METADATA.json — exact build source/run, protocol, artifact hashes,
    completed CI checks and limitations.
  6. SHA256SUMS.txt — checksums of the release assets above.

Keep raw captures, signing keys, complete session objects and machine-specific
configuration out of the release. Native standalone test executables stay in
Actions artifacts; they are not needed in the ordinary player download.

Build provenance and validation

Matching binaries come from source 3d87fd31fc993615879cca3f297958b0c66b339f,
main Actions run 37330983265.
All four jobs passed: portable regressions, production publication tests,
Android client and Windows server. Packaging checks verified the artifact hashes,
matching .51 protocol, APK native libraries, public signing fingerprint and
bundled license notices. The release tag adds documentation only; exact source,
tag commit and asset hashes are recorded in BUILD-METADATA.json.

The stable APK signing fingerprint matches alpha.7. Users of that stable build
can use the normal Android update path. Temporary-key PR APKs can differ; consult
signing guidance
before switching. Always replace the APK and server as a matching pair.

No new headset installation or live test was performed to publish this release.
Historical device results are scoped to their recorded source and configuration;
cloud build and artifact checks are not fresh hardware acceptance. Sustained and
human in-headset acceptance remain separate. Preserve alpha.7 for rollback and
follow the Virtual Desktop switching guide.

Upstream credits and dependency licenses are preserved in the packaged notices
and NOTICE.

Support development

Quest 3 direct eye-copy preview: ~104 fresh FPS, optional mode

Choose a tag to compare

@JMS1717 JMS1717 released this 02 Oct 00:48

Matching .15 Quest APK and Windows server add an optional direct eye-copy path and presentation-phase telemetry while keeping PyroWave decoding on Adreno with Vulkan compute.

At 2080 × 2208 per eye, 120-Hz runtime, 4:2:0, no foveated encoding, 1000 Mbps native USB/TCP, sequential same-scene 15-second screens delivered 103.71 / 103.63 fresh submitted FPS with direct copying versus 98.67 / 99.33 staging controls. Median completion fell from 9.32–9.40 to 8.72–8.74 ms. A single direct OpenXR BOOST screen reached 108.19 FPS / 8.29 ms; it is not replicated or endurance-validated.

Direct copy is off by default. Ordinary staging defaults do not claim a performance improvement over alpha.6. Follow the alpha.7 setup and opt-in guide. On Quest, set debug.q3pw.direct_eye_copy to 1 and restart this app; use 0 and restart to revert. Unsupported configurations fall back to staging. Actual copy counters confirm activation. Source leases and synchronous completion remain protected.

Tests requested GPU7/CPU6, with dynamic 690-MHz staging / 640-MHz direct clocks and 45°C battery temperature, thermal status 0. The APK does not apply performance debug properties automatically. Basic captures showed correct eyes, orientation and dominant colors; full image equivalence and human in-headset acceptance remain pending. Sustained fresh 120 FPS remains unmet: p1 nominal FPS ~60, p95 timestamp gaps ~16.7 ms. These are submission telemetry and ALVR latency estimates, not optical displayed frames or motion-to-photon measurements. No superiority over Virtual Desktop is established.

4:2:0 remains default. Batching and fused Haar remain off after live regressions/no gain; FP16 is not promoted. 144/207-Hz acceptance does not establish streaming performance; 240 Hz rejected gracefully on the tested setup. Wireless high-rate operation, thermal endurance, broad gameplay quality and larger resolutions remain research targets.

Download the matching APK and Windows ZIP, verify SHA256SUMS.txt, and preserve alpha.6 for rollback. Never mix .13 and .15 binaries. Stable APK certificate, build metadata, Android licenses and Windows license notices are included. All Android, Windows and regression jobs passed run 36942639620; binary source is ba415a8f21d25db3c8a1fb7a077a454dc189d9b6. The tag adds reviewed setup and full measurements.

This publication does not deploy anything to the maintainer's PC/Quest or resume paused hardware tests/automation. Preserve Virtual Desktop; connect to the PC in VD before Launch SteamVR.

Credits: ALVR, Hans-Kristian Arntzen's PyroWave and Granite, and Terminal-ennui's Galaxy XR integration. Quest port maintained by JMS1717.

Quest 3 native-resolution USB preview: ~100 fresh FPS, 4:2:0

Choose a tag to compare

@JMS1717 JMS1717 released this 01 Oct 22:49

Quest 3 native-resolution PCVR preview with matching .13 Android and Windows binaries, updated USB transport/complete-frame safety, upright client 3D performance overlay, Quest 3 Touch Plus emulation, bitrate slider/Auto controls, and experimental Haar Vulkan compute decode.

Measured preview, not sustained 120-FPS acceptance: 2080 × 2208 per eye, 120-Hz runtime, 4:2:0, no foveated encoding, manual 1000 Mbps over native ALVR USB/TCP delivered 99.7–100.7 fresh submitted FPS in separate 45-second fixed-chart captures. Instantaneous p1 was ~60 FPS. Median completion was 9.14–9.20 ms against the 8.33-ms budget. ALVR estimated latency was 65.6–68.1 ms; optical motion-to-photon was not measured. These trials used explicitly requested GPU7/CPU6, a reported 690-MHz GPU clock, and 44–45°C battery temperature. The APK does not automatically apply performance properties.

  • Keep 4:2:0 as default. Matched .11 chart trials gave ~100 fresh FPS at 1000 Mbps versus ~66 with 4:4:4 at 2000 Mbps. Full chroma improves fine saturated strokes but meaningfully regresses pacing, decode/completion cost and latency. It remains optional.
  • Fused Haar stays off. Limited native-resolution readbacks passed the existing <=1 code-value / <=0.05-dB source-PSNR-loss gate, but live fused decode fell to 71.8 FPS and 13.24-ms completion.
  • Eye-image reuse: no clear FPS gain in the short comparison; debug.q3pw.repeat_render=1 retains the redraw control. Client restart required after property changes.
  • Refresh capability detection: 144/207 Hz accepted on the tested headset; neither is sustained-stream validated. 240 Hz rejected gracefully in this setup.
  • CI: Android, Windows and regression jobs passed run 36933424039. Binary source is 1508dd7efe9f454aacc6c3eb305b76a7bbba3b7c; the release tag adds reviewed setup/findings.

Download Quest3-Pyrowave-dev.apk and Quest3-Pyrowave-Windows.zip together. Verify SHA256SUMS.txt. The APK uses this project's stable development certificate; BUILD-METADATA.json, APK-CERTIFICATE.txt, and Android/Windows upstream license notices are included.

Follow the launch, tested configuration and rollback guide. Start ALVR Dashboard.exe from the extracted server, install this distinct Quest APK, trust the headset, and use Devices → Wired Connection for USB. Preserve your previous matched installation and Virtual Desktop. Never mix the .13 timing/control ABI with older clients or servers.

Limitations: experimental Haar image quality; no sustained 120-FPS/thermal endurance acceptance, broad game-scene comparison, in-headset 4:4:4 superiority, wireless high-rate validation, or measured advantage over Virtual Desktop. Frame rates are fresh submission telemetry, not optical counters. One overlapping restart trial was explicitly excluded and repeated. Research continues on decode, conversion, completion and frame pacing.

Upstream credits: ALVR, Hans-Kristian Arntzen's PyroWave and Granite, and Terminal-ennui's Galaxy XR integration. This is a port and research project maintained by JMS1717.

Quest 3 full-frame preview: 1000 Mbps / 120 Hz / 4:2:0

Choose a tag to compare

@JMS1717 JMS1717 released this 30 Sep 17:21

Full-frame Quest 3 preview for manual acceptance.

  • Default: 1000 Mbps, 120 Hz, full panel-relative resolution, PyroWave CDF 9/7, 4:2:0.
  • Requests 2064 × 2208 per eye and pads to 2080 × 2208 for codec alignment. This is panel-relative size, not the larger lens-corrected OpenXR render recommendation.
  • Foveated encoding, client foveation, and gaze-following are disabled, including stale saved settings.
  • Optional 4:4:4 is available through the Full chroma checkbox; restart SteamVR after changing it.
  • Compute is the Quest 3 Auto path. Explicit Compute and Fragment choices remain available.
  • The APK probes extended refresh capability; 240 Hz requires explicit developer display scaling and is not guaranteed.

Install the APK, extract the Windows ZIP, run ALVR Dashboard.exe, register its SteamVR driver, and explicitly trust your headset. If switching from Virtual Desktop, enable the ALVR add-on in SteamVR before starting this session.

Build and installation instructions · Manual benchmark protocol

Both downloadable builds were produced by the pinned GitHub Actions recipe. The installed Windows streamer was also compiled locally from the matching Windows sources. The current full-resolution/4:2:0 configuration has not been visually or performance tested; no further headset benchmarks were run at the maintainer's request. Earlier Quest measurements in the repository are separately labelled and do not validate this preview.

Retain LICENSES.zip with the APK; the Windows ZIP includes its notices. SHA256SUMS.txt and APK-CERTIFICATE.txt identify the assets and signing certificate. Existing installations made with this repository's persistent key can upgrade in place. Older APKs signed with disposable development keys may require uninstalling only this separate Quest3-Pyrowave app once.

Credits and original licenses are retained for Terminal-ennui's research integration, ALVR, Themaister's PyroWave and Granite, Khronos OpenXR, and their dependencies. Project changes and publication are by JMS1717.