u/4erepaxa87

for Steam OS - eGPUBridge releases v0.2.alfa
▲ 12 r/eGPU

for Steam OS - eGPUBridge releases v0.2.alfa

Hey everyone,

I've been working on a Decky Loader plugin called eGPUBridge that solves a specific problem: managing external GPU display output on SteamOS handhelds.

The problem: When you connect an eGPU via USB4/Thunderbolt to a handheld running SteamOS (Legion Go, ROG Ally, etc.), switching between the internal

screen and the external display attached to the eGPU is a pain. You end up tinkering with config files, restarting sessions, or rebooting.

https://preview.redd.it/ukfswsvprr1h1.png?width=1274&format=png&auto=webp&s=4da9244e1c58fa6fda1f92c98858c69f37351e3e

https://preview.redd.it/cp1wupc7sr1h1.jpg?width=1396&format=pjpg&auto=webp&s=e5033ccfe20c908185014b83f3e1fbfdbea9a55b

https://preview.redd.it/9zybmkvasr1h1.jpg?width=1373&format=pjpg&auto=webp&s=cdfa60b64405835e9245bfd7ad1e8ff06820eecc

What eGPUBridge does:

- Auto-detects eGPU via USB4/Thunderbolt

- One-button switching between internal display and external TV

- Choose which GPU renders for the external display (eGPU vs integrated)

- Optional TV control — Wake-on-LAN, ADB, CEC (turn your TV on/off)

- Emergency hotkey to recover if something goes wrong

- Read-only USB4 dock status

How it works under the hood:

eGPU detection:

- Scans /sys/class/drm/card[0-9] — all DRM cards in the system

- Reads PCI vendor/device IDs from sysfs (/sys/class/drm/cardX/device/vendor, device)

- Built-in GPU is identified by the boot_vga=1 flag — everything else is considered external

- AMD GPUs recognized by vendor ID 0x1002, model name comes from lspci

- Not hardcoded to any specific hardware — works with any eGPU over USB4/Thunderbolt

Display detection:

- EDID of the monitor is read directly from /sys/class/drm/cardX-CONNECTOR/edid (binary data, monitor name parsed from the 0xFC descriptor)

- Connection status: connected / disconnected from sysfs

- Supported resolutions and refresh rates: parsed from modetest -c output (filters modes from 720p 50Hz and up)

- Priority: HDMI first (practical use case), then the rest

Display switching:

- Does NOT patch the system /usr/lib/steamos/gamescope-session file directly

- Uses plugin config files: output_order.conf (output order), prefer_vk_device.conf (GPU selection), gamescope_mode.conf (resolution)

- Gamescope is launched with parameters -O HDMI-A-1 (external) or -O eDP-1 (internal)

- --prefer-vk-device 1002:7550 tells gamescope which GPU to use for rendering

Internal panel shutdown (when running on TV):

- DPMS Off via modetest -w connectorID:DPMS:3 — monitor goes to "no signal" instead of black screen

- Backlight is saved and turned off (/sys/class/backlight/amdgpu_bl0/brightness = 0)

- Framebuffer blank + unbind fbcon — removes boot logo artifacts

TV control:

- Wake-on-LAN: magic packet sent to the TV's MAC address

- ADB: connects over IP, checks screen state (dumpsys display | grep mWakefulness)

- CEC: control via HDMI CEC protocol

- TV network status detected via ping (doesn't flood logs)

- TV config: /home/deck/.config/egpubridge-tv.conf (IP, MAC, ADB — not published)

PCIe link status:

- Speed and link width read from /sys/bus/pci/devices/ADDR/current_link_speed and current_link_width

- Fallback: parsing lspci -vv (LnkSta: line)

- Shows real USB4/TB throughput (e.g. 32GT/s x4)

Safety:

- Atomic config writes (write to .tmp first, then os.replace)

- Automatic backup of original gamescope-session before any changes

- Log rotation (max 2MB, keeps 700KB)

- Plugin does NOT restart SDDM for normal switching

Tested on: Lenovo Legion Go S (SteamOS) + AMD eGPU via ASMedia USB4 bridge. Should work on other handhelds with SteamOS and USB4/Thunderbolt — uses

generic detection via sysfs/DRM.

Open source: https://github.com/WowOne987/eGPUBridge (MIT license)

It's at v0.2.alfa — very early. I'd really appreciate it if anyone with an eGPU setup on SteamOS could try it out and report back. Even if it works —

that's valuable info. If it doesn't — even more valuable, because right now I only have one hardware combo to test on and I can't reproduce errors or edge

cases on other devices. Logs, screenshots, dmesg output — anything helps.

What hardware combos are you running? What features would you want?

reddit.com
u/4erepaxa87 — 4 days ago
▲ 8 r/eGPU

I built a Decky plugin for SteamOS eGPU display switching — eGPUBridge v0.7.27

Hi everyone,

I wanted to share a project I have been working on: **eGPUBridge**, a Decky Loader plugin for SteamOS Game Mode focused on external GPU display switching.

GitHub:

https://github.com/WowOne987/eGPUBridge

This is still experimental, but it is already working on my personal setup.

Why I made it

I use a Lenovo Legion Go S with SteamOS / SteamOS-like Game Mode, connected to an AMD Radeon RX 9070 / RX 9070 XT class eGPU through an ASMedia USB4 bridge/dock.

The external TV is connected through the eGPU HDMI output.

The problem I wanted to solve was simple:

SteamOS Game Mode can work with an eGPU, but switching between the internal display and the external TV/eGPU path can be annoying and risky if you have to manually edit Gamescope launch behavior or restart the wrong services.

I wanted a safer UI-driven way to:

* see which GPU/display path is currently active

* switch between internal display and TV/eGPU mode

* choose TV render modes like 4K60, 1440p120, 1080p60

* keep a recovery path if the TV/eGPU picture disappears

* avoid patching system Gamescope files directly

* avoid restarting SDDM/display-manager for normal switching

Main idea

The plugin tries to manage display switching through controlled runtime config files and a safer Gamescope wrapper path.

For TV/eGPU mode, the intended runtime state is usually:

  • output_order.conf = HDMI-A-1,eDP-1
  • prefer_vk_device.conf = 1002:7550
  • gamescope_mode.conf = selected mode or disabled

That makes Gamescope start with options similar to:

  • --prefer-vk-device 1002:7550
  • -O HDMI-A-1,eDP-1

For internal mode, the runtime state is usually:

  • output_order.conf = *,eDP-1
  • prefer_vk_device.conf = disabled
  • gamescope_mode.conf = disabled

That makes Gamescope start with output order similar to:

  • -O *,eDP-1

The important part is that the plugin should not patch /usr/lib/steamos/gamescope-session.

Normal switching should not restart sddm or the whole display manager.

The safer path is:

  1. update the plugin runtime config files
  2. restart only gamescope-session.target
  3. keep the internal display as the recovery target

Features right now

Current features in v0.7.27:

  • eGPU status display
  • internal display / external TV-eGPU switching
  • SMART toggle for Internal ↔ TV/eGPU
  • TV Mode selector
  • optional TV control through Wake-on-LAN / ADB / CEC
  • emergency recovery hotkey
  • read-only USB4 dock status
  • diagnostics / recovery buttons
  • recent events / debug info section

SMART button

The SMART button is the main switch.

The goal is simple:

  • if the internal display is active, switch to TV/eGPU
  • if TV/eGPU is active, switch back to internal display

This is meant to reduce the risk of getting stuck on a black screen.

On my tested device, holding Y1 + Y2 for several seconds can force recovery back to the internal display path.

TV Mode selector

TV Mode lets me choose render modes such as:

  • 4K60
  • 1440p120
  • 1440p60
  • 1080p120
  • 1080p60
  • 720p120
  • 720p60

This is useful because TVs and eGPU display paths do not always behave nicely if you rely only on automatic mode selection.

Optional TV control

TV control is optional. Display switching can work without it.

For my setup, I tested TV control with:

  • Wake-on-LAN
  • ADB
  • HDMI input switching

The idea is that the plugin can optionally wake the TV and switch the TV input before enabling the TV/eGPU display path.

This is useful because on some setups the eGPU/TV chain only behaves correctly when the TV is awake and already on the right HDMI input.

Important: I did not publish my private TV IP/MAC configuration. Those are local-only runtime settings.

Dock status

The dock/USB4 status is read-only.

The plugin can report USB4 / ASMedia bridge status, but it should not send ASMedia vendor commands, USB resets, or dock power-control commands.

I wanted the plugin to observe and diagnose the route, not blindly reset hardware.

Tested hardware

This was developed and tested on one personal hardware setup:

  • Lenovo Legion Go S
  • SteamOS / SteamOS-like Game Mode
  • AMD Radeon RX 9070 / RX 9070 XT class eGPU
  • ASMedia 246x USB4 bridge/dock path
  • External TV connected through the eGPU HDMI output
  • Optional TV control tested with Wake-on-LAN and ADB

This does not mean it is universal yet.

Different docks, GPUs, TVs, USB4 controllers, SteamOS versions, and Gamescope behavior may need changes.

What I learned

The hardest part was not only “make eGPU work”.

The harder part was making it recoverable.

A bad display switch can leave you with no visible picture. So the project became less about one button and more about safety layers:

  • keep internal display as recovery target
  • do not trust a single UI control until it is tested with gamepad focus
  • do not restart the whole display manager for normal actions
  • keep runtime state visible
  • make optional modules fail safely
  • make TV control optional
  • keep dock control read-only
  • make diagnostics easy to access

Current status

This is a public source snapshot, not a polished Decky Store package.

I am sharing it because it may be useful for other people working on SteamOS + eGPU setups, and because the code can probably become much better with feedback from others.

GitHub: https://github.com/WowOne987/eGPUBridge

Release: v0.7.27 initial public pre-release

Contributions welcome

I would be happy if other users or developers want to:

  • improve hardware detection
  • add more generic GPU/dock profiles
  • clean up the code
  • improve Decky UI structure
  • improve diagnostics
  • test other eGPU setups
  • improve TV control support
  • make packaging cleaner for Decky Loader

This started as a personal practical fix for my setup, but I think the idea could be useful for more SteamOS/eGPU users.

Keywords: SteamOS, Decky Loader, eGPU, USB4, Gamescope, Lenovo Legion Go S, AMD Radeon, external GPU, handheld PC

u/4erepaxa87 — 17 days ago