Scripts to get a Sunshine setup running on Bazzite with a virtual display (custom EDID + headless VKMS).
virtual_display_setup.sh— build and install a custom EDID RPM. Prompts for your EDID.bin, layers prerequisites if needed, patches initramfs, and appends the kernel arg.virtual_display_update.sh— update the EDID RPM in place. Detects the installededid_patchname fromrpm-ostree status, prompts for a new EDID.bin, rebuilds, and reinstalls.virtual_display_uninstall.sh— remove the EDID patch. Detects/removes theedid_patchRPM, deletes the dracut config, removes anydrm.edid_firmware=edid/...karg, disables the custom initramfs, and reboots.setup_sunshine_scripts.sh— installs the Sunshine prep/cleanup scripts to~/.local/bin, writesglobal_prep_cmdto~/.config/sunshine.conf, installs a systemd sleep hook that runs/usr/local/bin/force_display_wake.shafter resume, and drops anunlock_on_connect.shhelper that unlocks the session for userryanvialoginctl unlock-session.sunshine_sleep.sh/sunshine_cancel_sleep.sh— start/stop a per-user 60s suspend timer without sudo. Called by the prep/undo scripts.setup_startup_failsafe_service.sh— optional; installs a per-user systemd service that runsfix_displays.shon login to recover if only the prep ran.wake_on_lan_fix_nvidia.sh— installs a systemd resume hook (nvidia-display-wake.service) that wakes NVIDIA displays after suspend. Supports--mode=loginctl|xset|kscreen.uninstall_wake_on_lan_fix_nvidia.sh— removes thenvidia-display-wake.serviceresume hook.nvidia-resume-fix.sh— installs a KDE Wayland resume fix script at/usr/local/bin/kde-wayland-fix-resumeand wires it tosystemd-suspend.servicevia an override. Prompts for your output and mode.uninstall.sh— modular uninstaller with flags for the EDID patch, Sunshine helper scripts/wake unit, streamer autologin hooks, and the failsafe service. Supports--all,--dry-run, and--target-user.sunshine_tui.sh— TUI launcher that aggregates the scripts into a single menu-driven interface.
- Bazzite with
rpm-ostree - Root privileges (writes to
/etc, manages systemd, installs layered packages) - An EDID binary file to feed the scripts
- Clone this repo.
- Run
ujust setup-sunshineif not done already. - Run
for p in /sys/class/drm/*/status; do con=${p%/status}; echo -n "${con#*/card?-}: "; cat $p; doneto find a list of GPUs' free DP or HDMI output. - Edit connector names to match your hardware: in
virtual_display_setup.shreplaceHDMI-A-1in thedrm.edid_firmwarearg with the target output, and insunshine_do.sh/sunshine_undo.shreplace the defaultHDMI-A-1connector name with the one you found in step 3.
- Kill the Sunshine Process
- Run
sudo ./virtual_display_setup.shand supply your EDID.binpath when prompted. The script builds/installsedid_patch, updates initramfs, and appends the kernel arg, then reboots. Then follow the auto-unlock step below.
NOTE: If you do not want auto-unlock then remove the following lines from sunshine_do.sh:
"${SCRIPT_DIR}/unlock_on_connect.sh"
- Run
sudo ./setup_sunshine_scripts.sh. This installs the Sunshine prep/cleanup scripts to~/.local/bin, writes~/.config/sunshine.conf, installs/usr/local/bin/force_display_wake.shplus a systemd sleep hook at/etc/systemd/system-sleep/99-force-display-waketo run it after resume, and installs~/.local/bin/unlock_on_connect.shplus a sudoers entry that letsloginctl unlock-sessionrun without a password:
global_prep_cmd = [{"do":"bash -c \"${HOME}/.local/bin/sunshine_do.sh \\\"${SUNSHINE_CLIENT_WIDTH}\\\" \\\"${SUNSHINE_CLIENT_HEIGHT}\\\" \\\"${SUNSHINE_CLIENT_FPS}\\\" \\\"${SUNSHINE_CLIENT_HDR}\\\"\"","undo":"bash -c \"${HOME}/.local/bin/sunshine_undo.sh\""}]
The unlock helper targets the user session; edit setup_sunshine_scripts.sh (or the installed ~/.local/bin/unlock_on_connect.sh) if you need a different user.
3) Restart Sunshine.
Notes:
- The sleep helper scripts do not need sudo. They use per-user state under
${XDG_RUNTIME_DIR:-/tmp}andloginctl/systemctlto suspend. - If you run them directly from the repo, ensure they are executable (
chmod +x sunshine_sleep.sh sunshine_cancel_sleep.sh). The setup script handles this for the installed copies. - If you hit Wake on LAN issues on NVIDIA, try:
sudo rpm-ostree kargs --append-if-missing=nvidia.NVreg_PreserveVideoMemoryAllocations=1 sudo rpm-ostree kargs --append-if-missing=nvidia-drm.modeset=1 sudo rpm-ostree kargs --append-if-missing=nvidia.NVreg_EnableGpuFirmware=0. Also trysudo tee /etc/dracut.conf.d/99-edid.conf >/dev/null <<'EOF' install_items+=" /usr/lib/firmware/edid/[edidname].bin " EOF
- Run
sudo ./nvidia-resume-fix.shand enter your output (e.g.DP-3) and mode (e.g.2560x1440@165). - This installs
/usr/local/bin/kde-wayland-fix-resume, creates/etc/systemd/system/systemd-suspend.service.d/override.confwithExecStartPost=/usr/local/bin/kde-wayland-fix-resume, and reloads systemd.
Run setup_startup_failsafe_service.sh. This makes it to where it runs the sunshine_undo.sh script on startup in the event that when connecting to Sunshine only te sunshine_do.sh script runs. This can help fix black screens after logging in. (Ask me how I know :] )
- To swap to a new EDID later, run
sudo ./virtual_display_update.sh, provide the new.bin, and reboot when prompted.
- For a modular cleanup (EDID patch, helper scripts/wake unit, autologin hooks, failsafe), run
sudo ./uninstall.sh --allor pick flags (--virtual-display,--sunshine-scripts,--streamer-autologin,--failsafe-service). Use--dry-runto preview actions. - Reboot
The provided example_edid.bin supports various resolutions including 4K@60, 2420x1668@120Hz (iPad Pro), and 1280x800@90Hz, among other common resolutions.
It is recommended to use the samsung-q800t-hdmi2.1 EDID from v4l-utils. Use Custom Resolution Utility (CRU) to add more resolutions to the base EDID and export. CRU works fine under Wine.
LD_PRELOAD="" PROTON_HIDE_NVIDIA_GPU=0 PROTON_ENABLE_NVAPI=1 gamescope -f -b -H $(kscreen-doctor -j | jq '.screen.currentSize.height') --hdr-enabled --adaptive-sync -- %command%
From /u/psirrow:
If you're still having the problem (or for anyone else who finds this post), I had the same issue but I solved it by ticking a few more settings. This is what I have:
in "Settings/Display" I have:
"Disable GPU Blocklist" on
in "Settings/Interface" I have:
"Enable smooth scrolling in web views" on (may not be necessary)
"Enable GPU accelerated rendering in web views" on
"Enable hardware video decoding, if supported" on
setup_sunshine_scripts.sh now installs ~/.local/bin/unlock_on_connect.sh, which finds the active session for user ryan and runs loginctl unlock-session <id> using a sudoers drop-in (/etc/sudoers.d/sunshine-loginctl). Run the setup script with sudo so it can write the sudoers file. If your Sunshine user is not ryan, change the username in the script (or the installed unlock helper) before running it.
https://www.reddit.com/r/Bazzite/comments/1gajkpg/add_a_custom_resolution/
/u/Acru_Jovian
https://gist.github.com/iamthenuggetman/6d0884954653940596d463a48b2f459c
https://www.azdanov.dev/articles/2025/how-to-create-a-virtual-display-for-sunshine-on-arch-linux
https://www.reddit.com/r/linux_gaming/comments/1h2o0re/comment/mtq730l/
https://forums.linuxmint.com/viewtopic.php?t=440657&start=20