Radeon compute
Frame copies and colour conversion run on D3D12 compute queues beside the game's graphics work, instead of waiting behind it.
Windows game-streaming host for Moonlight · formerly Butterpollo
Stream your games from any AMD Radeon PC to any screen: a laptop, TV, phone, tablet, handheld or another PC. Rubylight drives AMD's encoder natively, prepares every frame on Radeon compute, and carries HEVC and AV1 in 10-bit HDR, or full-colour HDR 4:4:4 through PyroWave. It works with Moonlight and every other Sunshine-compatible client.
Windows x64 · free and open source (GPL-3.0)
14.34 ms
HEVC picture age under GPU load, native HDR at 120 fps
95th percentile 16.03 ms · local hardware decode
13.65 ms
AV1 picture age under GPU load, native HDR at 120 fps
95th percentile 18.00 ms · local hardware decode
120 fps
fresh pictures delivered under the synthetic GPU load
HEVC 119.99 · AV1 119.98 · 1968×2184 HDR
Rubylight 2.2.9, October 12, 2026 · RX 7900 XT · DDX · two runs per codec. Excludes remote network and display time. How these were measured
Follow one frame from your game to Moonlight, see the Radeon measurements, then get started. 60 seconds, original soundtrack.
Measured, not claimed
The October 12 native-HDR tests measured 14.34 ms average picture age for HEVC and 13.65 ms for AV1 at 1968×2184 and 120 fps. A timestamped picture passes through capture, encoding and independent hardware decoding on the same Radeon PC.
Rubylight 2.2.9 — October 12, 2026. The refresh passed 81 encoder probes, encoded and scored 148 AMF quality cases (32 defaults plus 116 settings variants), and passed 36 short loopback streams and 12 static-keyframe checks, alongside CPU, GPU, input and PyroWave component checks. Current measurements and scope
The AMF property sweeps passed 1,018/1,030 probes. Twelve 4K SDR cases with preanalysis enabled failed completion or frame-accounting checks; these probes do not measure full-stream latency. Settings results and failures
Both 4K120 HEVC runs and both 5120×1440/240 FPS saturation runs failed the stream gates. The audio/load/outage batch passed 6/11 full-stream checks, while 11/11 retained continuous audio. Those earlier stream batches used physical SDR capture with converted HDR output, separately from the native-HDR measurements.
Both 120-second audio streams passed, with 24/24 continuous audio windows. All four loss controls passed; all four injected-outage runs failed the normal gap checks. The short soak passed 64/67 cases, with three GPU-load freshness failures. Reconnect, switching, helper recovery and host working set, handle and thread growth checks passed. A 30-reconnect follow-up reproduced the rising GPU process counter as a reporting artifact: adapter-wide memory returned to baseline, with no sustained VRAM growth observed. Soak results and scope
The real Radeon 780M Wi-Fi receiver passed 20/20 stream checks: 12 HDR-output conversion runs and eight control/recovery runs. 19/20 calibrated timing records passed source validation; one had mismatched barcode timestamps and remains unavailable. Timing ends at frame assembly/enqueue, before decoder queueing, decoding or display. Current Wi-Fi results
Official Moonlight 6.2.0 completed two 165-second 1080p60 HEVC SDR sessions requesting 80 Mbps on the Radeon 780M laptop over Wi-Fi, reporting 59.99 FPS rendering in both. These component statistics do not measure full picture age. Both wrappers failed their immediate exit check; later checks confirmed natural exit with settings and pairings preserved. Stock Moonlight results
The native-HDR follow-up passed 28/28 DDX/WGC stream and timing checks and 4/4 HDR pixel checks. The separate SDR VRR capture sweep has 20 valid requested-mode phases; 12 phases remain unavailable because Windows selected different refresh rates. The historical private HDR/RTSS fixture source is unavailable.
Rubylight 2.2.9: October 12. Vibepollo 2.0: October 8, 2026, unchanged. Bar: average. Thin line: 95th percentile. Different physical desktop conditions; these are not a new matched comparison.
Current DDX results average two runs per codec and include local hardware decoding, excluding remote network and display time. The virtual HDR source remains at 120 Hz. The physical desktop changed from 2560×1440/120 Hz on October 8 to 5120×1440/240 Hz on October 12. Different dates and desktop conditions prevent a matched improvement claim. Current native runs and scope
| Picture age, average / p95 / p99 | Rubylight rc.24 | Vibepollo 2.0 |
|---|---|---|
| Beside a game capped at 60 fps | ||
| 1968×2184 HEVC HDR 120 fps | 19.61 / 21.56 / 23.10 ms host 3.4 ms | 26.96 / 37.62 / 39.25 ms host 8.3 ms |
| 1968×2184 AV1 HDR 120 fps | 17.15 / 18.96 / 22.18 ms host 3.1 ms | 24.53 / 36.77 / 38.05 ms host 7.4 ms |
| 1920×1080 HEVC HDR 60 fps | 17.84 / 21.78 / 22.84 ms host 2.2 ms | 20.55 / 22.55 / 22.66 ms host 5.7 ms, one run |
| No game running | ||
| 1968×2184 HEVC HDR 120 fps | 17.81 / 18.94 / 19.56 ms | 19.97 / 20.43 / 20.87 ms |
| 1968×2184 AV1 HDR 120 fps | 17.42 / 18.10 / 18.62 ms | 18.88 / 19.54 / 19.90 ms |
| 2560×1440 HEVC HDR 120 fps | 17.09 / 17.99 / 18.46 ms | 17.19 / 17.68 / 17.93 ms |
Rubylight rc.24 and the pinned Vibepollo 2.0 build on the same GPU, alternating in one batch, two runs per cell. Identical settings: native AMF at ultra-low latency, Desktop Duplication capture, a virtual HDR display. The picture is decoded in hardware by an independent client on the same PC, which isolates the host from the network so the two can be compared precisely; the Wi-Fi results below add a real network. Beside the game Rubylight also delivered more fresh pictures: 117–120 a second against 103–118. Runs and settings
The October 12 Rubylight 2.2.9 hardware-receiver matrix passed 20/20 ordinary stream checks, with 19 valid calibrated timing records. It measures arrival at assembly/enqueue from a physical SDR source, including HDR-output conversion. The 1.177 ms clock-fit diagnostic is not a proven error bound. The following October 8 measurements retain their original method and date.
A client on 5 GHz Wi-Fi, decoding in hardware, against the host on Ethernet. "Received" is when the client starts decoding a fully received picture.
| HDR, render to received | Average / p95 / p99 | Fresh pictures | Host |
|---|---|---|---|
| 1968×2184 AV1, 120 fps, 80 Mbps | 13.54 / 14.33 / 14.93 ms | 120.0/s | 3.0 ms |
| 1968×2184 HEVC, 120 fps, 80 Mbps | 14.13 / 14.97 / 15.90 ms | 120.0/s | 3.7 ms |
| 2560×1440 AV1, 120 fps, 50 Mbps | 13.34 / 14.15 / 16.12 ms repeat: 13.28 / 14.07 / 15.63 ms | 120.0/s | 2.8 ms |
| 2560×1440 HEVC, 120 fps, 50 Mbps | 13.67 / 14.69 / 19.87 ms | 120.0/s | 3.1 ms |
| 1920×1080 AV1, 60 fps, 20 Mbps | 12.91 / 15.05 / 17.89 ms | 60.6/s | 2.2 ms |
| 1920×1080 HEVC, 60 fps, 20 Mbps | 12.99 / 14.15 / 16.62 ms | 60.5/s | 2.4 ms |
Rubylight rc.24, October 8, 2026, one 30-second run per row. The client's clock was synchronised to the host with 200 ms pings (error about ±0.6 ms). Every picture arrived and decoded. Method and clock sync
With Moonlight on the same link, a 1440p120 AV1 stream held 119.7 fps with no loss, and with the host dropping 20 ms of video every 1.5 s, all 59 lost frames were recovered without a keyframe at 117.7 fps.
What you get
Frame copies and colour conversion run on D3D12 compute queues beside the game's graphics work, instead of waiting behind it.
AMD's encoder driven directly, not through a generic wrapper, and tuned per codec from VMAF measurements. Driver quirks get workarounds, and lose them once AMD fixes the driver.
Ten-bit BT.2020/PQ from capture to the encoder, with HDR metadata in the keyframes, checked by a test. H.264 is there too.
A colour sample for every pixel keeps coloured text and edges crisp, over a fast local network with Rubylight Android, our own client, or any PyroWave-capable Moonlight client.
A display per device, shared or off, with exclusive, extended, primary and isolated layouts, HDR, and your own layout restored after the stream.
Steam and Playnite sync, per-app and per-device settings, RTSS frame limits, Lossless Scaling, and a 1000 Hz VRR mode.
Xbox, DualSense with adaptive triggers and Switch Pro pads from one signed driver. With usbip-win2 installed, a Steam Deck can show up on the host as a real Steam Deck controller.
Streaming, protocol, native helpers, the Windows service and the installer are Rust, with a web console for pairing, the library and live encoder timings.
Install. Pair Moonlight. Play.
Run the installer from the release. Installing over Apollo, Vibepollo or Butterpollo keeps your settings, paired devices, app library and covers.
Go to https://localhost:47990 on the host PC and create your local account.
Add your PC in Moonlight or any Sunshine-compatible client, enter its PIN under Devices, then launch Desktop. Start at 1080p60, then raise resolution, frame rate and HDR.
What users say
Dude... What the fuck is this host? I could not believe it. It's the lowest latency I got after testing a ton of hosts. Congratulations, dude.
From 10 ms encoding to 5 ms in 4K 60 fps, btw :) I tried it with PyroWave and it was close to native. Really impressive.
Switched to PyroWave on RC19. I honestly see no difference between host and client. Amazing work!
Fantastic job! Host processing latency has never been this low. Clean UI too. Well done!
Quotes from Reddit, lightly edited for typos. Read more of what users say
Why it exists
The protocol started as NVIDIA's GameStream, and the hosts that replaced it kept NVIDIA first. Upstream Sunshine has had a native NVENC encoder since 2023, while AMD still goes through FFmpeg's generic AMF wrapper. So Radeon owners have spent years hearing their cards are just worse at streaming. Most of the time the card was never the problem. Nobody had sat down with it.
Rubylight is a host rebuilt in Rust around the Radeon frame path, from capture to the encoder, for every Radeon owner who wants to play away from the desk.
Documentation