Skip to content

Instantly share code, notes, and snippets.

@robertkirkman
Last active August 7, 2024 18:35
Show Gist options
  • Save robertkirkman/753922262259486ec417e5ff8b5b924b to your computer and use it in GitHub Desktop.
Save robertkirkman/753922262259486ec417e5ff8b5b924b to your computer and use it in GitHub Desktop.
How to record or stream SteamOS 3.X Gaming Mode

How to record or stream SteamOS 3.X in gamescope (Gaming Mode)

Here is another method that uses Flatpak and obs-vkcapture, which don't meet my personal needs but are very likely to be useful for you. In the comments there there is also an obs-gstreamer method.

Here is another method for recording that has its own GUI for Gaming Mode built with Decky Loader.

Force SteamOS to behave very much like Arch Linux

Key phrase: very much like, not identical. Always treat this as more unstable than Manjaro and only expect support with it in my comments section here.

  1. Set a password (if you haven't already) and disable read-only rootfs (yes this means after updating SteamOS [not Steam Client] this will all be deleted and you will have to do all this again if you want to stream again)
passwd
sudo steamos-readonly disable
  1. (OPTIONAL) The on-Steam Deck OBS guide is written in a way that shouldn't require a separate device to actually execute any commands (the Sunshine guide requires a separate device for Moonlight), but for much less awkward and more efficient CLI activity, especially if you don't have a physical keyboard that's compatible with your Steam Deck, you can enable the SSH server to allow remotely connecting using your preferred keyboard-endowed device
sudo systemctl enable --now sshd
  1. Set up pacman. What you hope to see after sudo pacman -Syyu is "there is nothing to do", or at least very few upgrades available. That means that the repositories currently selected in your pacman.conf contain packages very close to the rootfs image that rauc last installed, and the fewer packages that differ from your rootfs' preinstalled packages you have to install, the less likely it is you will encounter severe issues.

WARNING: If something goes wrong, this can mess up your rootfs, but luckily there is a backup rootfs in every OFW Steam Deck that you can access with the ・・・ + ⏻ button combination at boot, from which you can recover if that happens.

  • On February 6th, 2024, the precompiled pacman package repository that Valve provides for us, steamdeck-packages.steamos.cloud, had 2 active repository sets, -3.5 and -main

  • steamos-select-branch -l had 5 branches, rel, rc, beta, bc and main

  • the rel branch had SteamOS 3.5.7 with build number 20231122.1, which was

    • 6 packages ahead and 20 packages behind the -3.5 repository set
    • 6 packages ahead and 44 packages behind the -main repository set
    • For this reason, I think the -3.5 repository set was the best choice for this branch
  • the rc, beta and bc branches ALL had SteamOS 3.5.14 with build number 20240202.1, which was

    • 0 packages ahead and 2 packages behind the -3.5 repository set
    • 3 packages ahead and 41 packages behind the -main repository set
    • For this reason, I think the -3.5 repository set was the best choice for these branches
  • the main branch had SteamOS 3.6 with build number 20240119.1000, which was

    • 34 packages ahead and 4 packages behind the -3.5 repository set
    • 0 packages ahead and 13 packages behind the -main repository set
    • For this reason, I think the -main repository set was the best choice for this branch
curl https://gist.githubusercontent.com/robertkirkman/753922262259486ec417e5ff8b5b924b/raw/9866b808cf82ccababcc066aafe2da6a51f5b453/pacman.conf | sudo tee /etc/pacman.conf
if [[ $(steamos-select-branch -c) == 'main' ]]; then sudo sed -i 's/3.5/main/g' /etc/pacman.conf; fi
sudo pacman-key --init
sudo pacman-key --populate
sudo pacman -Syyu
  1. Reinstall all corrupted packages that once contained header files before Valve deleted /usr/include

You might see a few errors generated by mkinitcpio during the post-transaction hooks phase. They are spurious and can be safely ignored.

sudo pacman -S $(pacman -Ql | grep -e include -e pkgconf | cut -d' ' -f1 | awk '!a[$0]++')
  1. Install some compiler toolchain packages. At this point you could now add as many pacman packages as you want and could fit into the 5 GB root partition, bearing in mind that even upstream Arch Linux itself has periodically had packages in their official repositories that break the system when installed, so all pacman users are expected to have experience with the packages they're installing, use caution, and prepare for the possibility of a bug.
sudo pacman --overwrite=/etc/ld.so.conf.d/fakeroot.conf -S base-devel meson cmake
  1. (OPTIONAL) Install your preferred terminal emulator (unless you prefer konsole which is preinstalled), Launch KDE Plasma Xorg (Desktop Mode), open Steam LIBRARY tab, and add it as a non-Steam game; here kitty is used as an example. At this time, I would also suggest you add a large number of dummy/duplicate non-Steam game entries for future use, because if you wish to remain in Gaming Mode, you will be able to change preexisting non-Steam game entries to add new shortcuts, which is otherwise impossible without switching to Desktop Mode.
paru -S kitty
  • Suggested kitty Launch Options in non-Steam game properties:
LD_PRELOAD= %command% --start-as=fullscreen

Sunshine

  1. Clone the repository of the AUR package for sunshine, which is maintained by the upstream developer, apply a patch of my own design that makes sunshine usable in Steam Deck's Gaming Mode, then build and install sunshine using makepkg
git clone https://aur.archlinux.org/sunshine.git
cd sunshine
(curl https://gist.githubusercontent.com/robertkirkman/753922262259486ec417e5ff8b5b924b/raw/2bb65f89ad3a0e0219c2a7f5116ed18fa2c0a8d0/sunshine-aur-steamdeck-gamingmode.patch && echo) | git apply -v
makepkg -si
  1. Enable DRM capture mode in sunshine

WARNING: setcap is a security risk and after running it, all users and software with executable permission for the affected binary can be considered effectively root-equivalent (in this context, they would definitely be able to see your screen for example). To remove setcap permissions from any binaries granted this, use sudo setcap -r /path/to/file.

sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
  1. Create symlink to stub xrandr to work around Error: [xrandr --output HDMI-1 --mode 1920x1080] failed with code [1], then run sunshine:
ln -s /bin/true xrandr
export PATH=$(pwd):$PATH
sunshine &
  1. Make sure the Steam Deck is connected to Wi-Fi or Ethernet, and identify its local IP address for use in the following steps
ip a
  1. Now move to the LAN device you would like to connect to the Steam Deck's Sunshine from and install Moonlight and a browser capable of accessing Sunshine's PIN entry box, for example epiphany or ungoogled-chromium; example command for an Arch Linux device with yay

Unfortunately, OBS cannot record the moonlight-qt window in gamescope without adding the additional overhead of the OBS section below this section, and epiphany is bugged and does not work in gamescope, so both of these softwares can only be effectively used to connect to Steam Deck Gaming Mode Sunshine from a separate device.

yay -S moonlight-qt epiphany
  1. Launch your browser, connect to the Sunshine web server on the Steam Deck where you replace 192.168.12.146 with your Steam Deck's local IP address, accept all warnings (which occur on every default copy of Sunshine) and create a username and password for administration of Sunshine, re-enter the new credentials to log in, then navigate to the "PIN Pairing" entry box
epiphany https://192.168.12.146:47990
  1. Launch Moonlight and add the Steam Deck's IP address as a new device, then type the PIN provided by Moonlight into the PIN box in the browser window

Sometimes Moonlight will fail to authenticate the first time even if the PIN is correct, just keep trying until you can click on the Steam Deck's entry and see the "Desktop" button.

moonlight
  1. Click the Steam Deck's entry in Moonlight and the "Desktop" button, you can now see the entire Steam Deck screen and almost every menu and game, with a few exceptions - sometimes the onscreen keyboard and Quick Settings menu are invisible in Moonlight, but overall, Sunshine configured this way is capable of capturing much more, more reliably, than any other software. You can also capture the moonlight-qt window using OBS, which works better than the OBS guide below as long as you have this other system to run Moonlight on. Sometimes, sunshine might crash or Moonlight might spontaneously disconnect; if that happens, just restart both and everything will start working again.

If you use Sunshine+Moonlight for streaming-based netplay (someone playing on Steam Deck while someone else plays on another device), you might want to configure advanced audio settings (such as making sure the person using Moonlight can hear the game audio, but not themselves through your VOIP software like Discord). Steam Deck contains two distinct digital sound controllers that behave almost the exact same way their desktop PC counterparts do, which makes such advanced audio settings both possible and nearly identical to how they would be on a desktop Arch Linux PC. Therefore, for now I consider such settings outside the scope of this guide, but if you struggle with audio settings, let me know and I will consider expanding this to cover that common audio use case.

OBS

  1. Install OBS
paru -S obs-studio
  1. If you do not have any unused dummy shortcuts to populate with OBS, launch KDE Plasma Xorg (Desktop Mode), open Steam and add OBS to Library as a non-Steam game, then right click on it, click Properties, and place the following text exactly as shown in the Launch Options box:
LD_PRELOAD= QT_QPA_PLATFORM=xcb %command%
  • There are three possible capture sources for OBS that currently work in gamescope. obs-kmsgrab used to work, and does still work in Xorg as a test, but I think it would need more updates to work with present-day gamescope:

OBS with FFmpeg

Unfortunately, this is a very messy method that encodes twice, stutters a lot, and sometimes looks green.

  1. Install FFmpeg

WARNING: setcap is a security risk and after running it, all users and software with executable permission for the affected binary can be considered effectively root-equivalent (in this context, they would definitely be able to see your screen for example). To remove setcap permissions from any binaries granted this, use sudo setcap -r /path/to/file.

paru -S ffmpeg
sudo setcap cap_sys_admin+ep $(readlink -f $(which ffmpeg))
  1. First create a new Scene in OBS, then add a new Media Source to the Scene and uncheck Local File. Then add the following and click OK
  • Input: udp://localhost:4444

  • Input Format: udp

  1. Switch to gamescope, navigate to Library and launch your terminal emulator, then execute this command; ffmpeg will crash anytime you leave the Steam client window by selecting a game or non-Steam app, and this should automatically restart it
while true; do ffmpeg -thread_queue_size 512 -framerate 60 -device /dev/dri/card1 \
     -f kmsgrab -i - -vaapi_device /dev/dri/renderD128 \
     -vf 'hwmap=derive_device=vaapi,scale_vaapi=format=nv12' \
     -c:v h264_vaapi -bf 1 -f mpegts udp://localhost:4444; done
  • You will also need to bind Ctrl+C to actually be able stop this capture with the least difficulty; navigate to "Controller settings" for your terminal emulator's non-Steam game entry and bind buttons to these keys, as pictured below. It is very possible that there is a better way of controlling ffmpeg without an external keyboard than this, but unfortunately I haven't found that way yet.

image

  1. Navigate to Library, launch OBS and start your stream or recording now. ffmpeg will often crash when you switch windows, but wait for a few seconds each time you do. The loop will automatically reset ffmpeg, and anything you can look at should be captured. When you are done, navigate to OBS and stop your stream or recording, then navigate to your terminal emulator and hold down your Ctrl+C keybind for a few seconds to kill the ffmpeg loop

Sometimes, ffmpeg will only record a small rectangular portion of the screen and the rest will be black. I don't know exactly why this happens and I haven't found any way to consistently prevent it, but it doesn't happen every single time, so if the source looks incomplete in OBS, kill the loop and try running it again until it looks acceptable.

Secret Section

Build and Install AUR package: suyu-dev-qt6-git

I've been doing this in private this whole time but wanted to document it somewhere. This changes all the time. Sometimes you'll have to edit lots of dependency packages, but sometimes when SteamOS is very close to upstream Arch Linux, it's not necessary to edit anything. This is a snapshot of the steps that were necessary in March 2024.

  1. Make some space if the 5GB root partition is too full to do this. If you need locales other than English, you would need to change the locale here to yours and also edit /etc/locale.conf.
sudo rm -rf /usr/share/{man,doc,gtk-doc}
sudo mv /usr/share/locale/locale.alias .
sudo rm -rf /usr/share/locale/*
sudo mv locale.alias /usr/share/locale/
echo 'es_US.UTF-8 UTF-8' | sudo tee /etc/locale.gen
sudo locale-gen
  1. Install SteamOS-specific dependencies and build Suyu. Accept all prompts.
paru -S vulkan-headers-git
paru -S suyu-dev-qt6-git

Special thanks to people who helped me with various parts of this guide: scaled#4479 logan2611#2351 kamae#7499 2zd9R#9421 and to the developers of all the software involved

#
# /etc/pacman.conf
#
# See the pacman.conf(5) manpage for option and repository directives
#
# GENERAL OPTIONS
#
[options]
# The following paths are commented out with their default values listed.
# If you wish to use different paths, uncomment and update the paths.
#RootDir = /
DBPath = /usr/lib/holo/pacmandb/
#CacheDir = /var/cache/pacman/pkg/
#LogFile = /var/log/pacman.log
#GPGDir = /etc/pacman.d/gnupg/
#HookDir = /etc/pacman.d/hooks/
HoldPkg = pacman glibc
#XferCommand = /usr/bin/curl -L -C - -f -o %o %u
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#CleanMethod = KeepInstalled
Architecture = auto
# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
#IgnorePkg =
#IgnoreGroup =
#NoUpgrade =
#NoExtract =
# Misc options
#UseSyslog
Color
#TotalDownload
# We cannot check disk space from within a chroot environment
CheckSpace
#VerbosePkgLists
ParallelDownloads = 10
# By default, pacman accepts packages signed by keys that its local keyring
# trusts (see pacman-key and its man page), as well as unsigned packages.
SigLevel = Required DatabaseOptional
LocalFileSigLevel = Optional
#RemoteFileSigLevel = Required
# NOTE: You must run `pacman-key --init` before first using pacman; the local
# keyring can then be populated with the keys of all official Arch Linux
# packagers with `pacman-key --populate archlinux`.
#
# REPOSITORIES
# - can be defined here or included from another file
# - pacman will search repositories in the order defined here
# - local/custom mirrors can be added here or in separate files
# - repositories listed first will take precedence when packages
# have identical names, regardless of version number
# - URLs will have $repo replaced by the name of the current repo
# - URLs will have $arch replaced by the name of the architecture
#
# Repository entries are of the format:
# [repo-name]
# Server = ServerName
# Include = IncludePath
#
# The header [repo-name] is crucial - it must be present and
# uncommented to enable the repo.
#
# The testing repositories are disabled by default. To enable, uncomment the
# repo name header and Include lines. You can add preferred servers immediately
# after the header, and they will be used before the default mirrors.
#[testing]
#Include = /etc/pacman.d/mirrorlist
[jupiter-3.5]
Include = /etc/pacman.d/mirrorlist
[holo-3.5]
Include = /etc/pacman.d/mirrorlist
[core-3.5]
Include = /etc/pacman.d/mirrorlist
[extra-3.5]
Include = /etc/pacman.d/mirrorlist
#[community-testing]
#Include = /etc/pacman.d/mirrorlist
[community-3.5]
Include = /etc/pacman.d/mirrorlist
[multilib-3.5]
Include = /etc/pacman.d/mirrorlist
# An example of a custom package repository. See the pacman manpage for
# tips on creating your own repositories.
#[custom]
#SigLevel = Optional TrustAll
#Server = file:///home/custompkgs
diff --git a/PKGBUILD b/PKGBUILD
index 0d16677..b1c19e8 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -76,7 +76,9 @@ build() {
-Wno-dev \
-D CMAKE_INSTALL_PREFIX=/usr \
-D SUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
- -D SUNSHINE_ASSETS_DIR="share/sunshine"
+ -D SUNSHINE_ASSETS_DIR="share/sunshine" \
+ -D SUNSHINE_ENABLE_TRAY=OFF \
+ -D SUNSHINE_REQUIRE_TRAY=OFF
make -C build
}
@LJ-Software
Copy link

Thank you so much for making this guide! It's exactly what I'm looking for.
Unfortunately though I get an error when trying to build sunshine with your patch:

(deck@steamdeck sunshine)$ makepkg -si
==> Making package: sunshine 0.14.1-1 (Tue 25 Oct 2022 09:17:34 PM CDT)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Updating sunshine git repo...
Fetching origin
  -> Found sunshine-steamdeck-gamingmode.patch
==> Validating source files with sha256sums...
    sunshine ... Skipped
    sunshine-steamdeck-gamingmode.patch ... Passed
==> Extracting sources...
  -> Creating working copy of sunshine git repo...
Reset branch 'makepkg'
==> Starting prepare()...
Checking patch src/platform/linux/kmsgrab.cpp...
Applied patch src/platform/linux/kmsgrab.cpp cleanly.
==> Removing existing $pkgdir/ directory...
==> Starting build()...
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find Threads (missing: Threads_FOUND)
Call Stack (most recent call first):
  /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake/Modules/FindThreads.cmake:238 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  third-party/Simple-Web-Server/CMakeLists.txt:18 (find_package)


-- Configuring incomplete, errors occurred!
See also "/home/deck/Programs/sunshine/src/build/CMakeFiles/CMakeOutput.log".
See also "/home/deck/Programs/sunshine/src/build/CMakeFiles/CMakeError.log".
==> ERROR: A failure occurred in build().
    Aborting...

This sounds like a missing dependency maybe? Any thoughts on what could be wrong are appreciated.

@robertkirkman
Copy link
Author

Hi LJ-Software, I'm very sorry I didn't see your message before now. I will be updating this patch today because the sunshine AUR package was recently updated (after your message). In the process I will attempt to reproduce your issue, but at first glance it looks to me like you might have encountered a problem at Step 4 of the Prerequisites. Could you double check that step and explain any problem if you see one?

@robertkirkman
Copy link
Author

robertkirkman commented Nov 1, 2022

OK, the patch here is now current to the latest versions of the sunshine AUR package.
I also erased my Steam Deck's SSD and reinstalled SteamOS using the official Steam Deck recovery image, then tested all the steps of this guide on it once again. Everything works exactly as expected, so unfortunately I have still been unable to reproduce your issue.
Doing this did remind me, though, that on clean imaged Steam Decks, the crucial step 4 of the Prerequisites does cause dracut to generate large amounts of spurious errors, but they do not actually break anything or interfere with this process, so they can be safely ignored. I added a note about that to the guide - I'm sorry I didn't before, I should have realized those errors might be confusing.

@andres-asm
Copy link

@robertkirkman hi, does the patch still work for you on the latest master?
I tried but the screen is still cut out.

@robertkirkman
Copy link
Author

robertkirkman commented Nov 16, 2022

hi @fr500 , thanks for the feedback. I just checked and the patch definitely does still work for me, with both master branch and the 0.15 release this guide suggests. When you say "the screen is still cut out", do you mean that the whole viewport or only a portion of the viewport is black in Moonlight? If the former, I think you might need to double check Step 4 of the Sunshine section and also ensure that /usr/include/libdrm/ exists and has been populated by Step 4 of the Prerequisites prior to beginning the Sunshine section, but if the latter, you should double check Step 2 of the Sunshine section and make sure that git diff in the sunshine/src/sunshine folder prints the patch to make sure it was correctly applied during the execution of makepkg. Please let me know whether you are successful or explain in detail any further problems you encounter.

An unrelated note: For the time being, using this guide on the new SteamOS 3.4 requires recompiling the graphics driver due to a butterfly effect originating with the h264 licensing hell controversy. The problem seems to be resolved at time of writing in upstream Arch Linux, but I will wait to see if developments occur in SteamOS before adding the recompilation steps, which do enable the rest of this guide to work on SteamOS 3.4, to this guide. In the meantime, it will continue to work just fine on SteamOS 3.3.

@andres-asm
Copy link

Oh, well I just applied the patch and built with the github CI to the same flatpack...
But yeah I still get something like this:

image

My interest is recording too, and I just discovered that steam remote play works with the steam deck out of the box, basically I can stream to my PC without sunshine or anything. A good avenue would be to write a custom remote play client.

@robertkirkman
Copy link
Author

@fr500 oh, I've never used the Flatpak but if you describe the process you used to create it, I could follow that and try to figure out what you need to do.
It looks to me as though the patch isn't being fully included in your Flatpak build.

@robertkirkman
Copy link
Author

@fr500 I just looked at your repository, if you're seeing those print statements you wrote when you run Sunshine, then your changes are being applied. In that case, you should make sure that:

  • You are using Gaming Mode (the patch is not required for Desktop Mode)
  • You are using the Steam Deck internal display (the patch is not required for external monitors)

@robertkirkman
Copy link
Author

robertkirkman commented Nov 17, 2022

I just compiled your repository (using my build process rather than a Flatpak) and:

  • I can see your print statements in the Sunshine log
  • The changes you applied are correctly working around the issue shown in your screenshot (entire viewport visible in Moonlight)

For this reason, I suspect your source code might not be the source of the Flatpak you are using. I recommend you first verify that the print statements you added are showing up in your Sunshine log.
If they are, then the only remaining explanation is that, bizarrely, this fix I came up with somehow only works on native builds and not Flatpak builds, and I can't imagine why.

@lyndonguitar
Copy link

lyndonguitar commented Nov 17, 2022

I am having issues with step 3 of sunshine here, it displays this error and seem to fail installation of sunshine as the next steps dont work

This was the error and abort message while running step 3:

CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find Threads (missing: Threads_FOUND)
Call Stack (most recent call first):
/usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake/Modules/FindThreads.cmake:238 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
third-party/Simple-Web-Server/CMakeLists.txt:18 (find_package)

-- Configuring incomplete, errors occurred!
See also "/home/deck/sunshine/sunshine/sunshine/src/build/CMakeFiles/CMakeOutput.log".
See also "/home/deck/sunshine/sunshine/sunshine/src/build/CMakeFiles/CMakeError.log".
==> ERROR: A failure occurred in build().
Aborting...

EDIT: Just read the comments and someone has the same issue. currently reading the rplies and troubleshooting...

EDIT2: I just got past through the error but i dont know exactly what I did, but what I did were in case it would be a help to anyone

  1. Re do of step 4 prerequisite
  2. step 3 still didnt work, so I deleted the whole sunshine folder on /home
  3. re do all steps of sunshine from step 1
  4. when i got to step 3 it finally worked

thanks, will continue the setup and report any issues

EDIT3:
Good news is that I have managed to make it work and added it as a service as well via systemd. It runs on startup automatically even straight to game mode.

However I realize I'm almost deback to zero As this is exactly where I was a few days ago when trying it out, but with slight improvements:
black screen on game mode, desktop mode still gets borked randomly
but I notice I can send touch inputs to the steam deck (not sure if I can do this before)

Maybe this is something to do with my SteamOS being version 3.4?

@robertkirkman
Copy link
Author

robertkirkman commented Nov 17, 2022

@lyndonguitar Hi, if you have black screen in the entire viewport of Moonlight (NOT like fr500's screenshot where part of the viewport is visible), double check Step 4 of the Sunshine section and make sure that /usr/include/libdrm is populated and that sunshine prints:

[2022:11:17:11:49:54]: Info: Screencasting with KMS
[2022:11:17:11:49:54]: Info: Found monitor for DRM screencasting

because if you do not see that, then Sunshine cannot stream Gaming Mode
After achieving the above, on SteamOS 3.4 I believe you will always get Error: Couldn't import RGB Image: 00003009 in Sunshine log at the moment that Moonlight connects to Sunshine running in Gaming Mode until you recompile your graphics driver with certain compile options. I haven't added that to the guide yet but I will give a couple of tips if you are desperate for this to work on SteamOS 3.4:

  • You need this source package
  • The compile options you need are -D video-codecs=h264dec,h264enc \ which should be added just after line 73 of the jupiter-mesa PKGBUILD
  • There are some dependency conflicts when you try to install the resulting packages which I successfully got through and can confirm that allows this to work on SteamOS 3.4, but I haven't thought of the fastest reliable way to write the directions in this guide. I hope Valve does something that removes the need to recompile the graphics driver soon.

@robertkirkman
Copy link
Author

robertkirkman commented Nov 17, 2022

Also, I just realized that the source of some of the troubles you guys are having might be that the Prerequisite steps here do indeed unfortunately become harder on SteamOS 3.4. In order for them to work without messy workarounds, an exactly correct /etc/pacman.conf and /etc/pacman.d/mirrorlist are needed, and unfortunately the /etc/pacman.conf included with previous releases of SteamOS 3 (which will still be present in your /etc/ folder because SteamOS' rauc updater does not erase that folder) is insufficient for SteamOS 3.4 at time of writing. I have personally been using Sunshine on SteamOS 3.4 by using quick edits to those files and workarounds on the fly, but I don't know any way that I would recommend for others to use yet. My hope is that Valve will include an updated /etc/pacman.conf and/or /etc/pacman.d/mirrorlist in the next SteamOS recovery image that they release, but they haven't released one based on SteamOS 3.4 yet. In the meantime I will continue to search for more complete and reliable solutions for SteamOS 3.4.

@robertkirkman
Copy link
Author

robertkirkman commented Nov 23, 2022

I've learned the correct way to calculate the necessary /etc/pacman.conf contents; briefly, if you are using SteamOS 3.4 right now, your /etc/pacman.conf must contain these repository names:

[jupiter-main]
Include = /etc/pacman.d/mirrorlist
SigLevel = Never

[holo-main]
Include = /etc/pacman.d/mirrorlist
SigLevel = Never

[core-main]
Include = /etc/pacman.d/mirrorlist

[extra-main]
Include = /etc/pacman.d/mirrorlist

[community-main]
Include = /etc/pacman.d/mirrorlist

[multilib-main]
Include = /etc/pacman.d/mirrorlist

and your /etc/pacman.d/mirrorlist must contain this:

Server = https://steamdeck-packages.steamos.cloud/archlinux-mirror/$repo/os/$arch

This is because SteamOS 3.4 is currently still in the Steam Deck "OS Preview" channel. When it's released to the "Stable" channel, it's likely but not absolutely certain that Valve will quickly update their other repositories to match, and the *-main repositories will begin to receive updates related to a future "Preview".

These repositories clean up a lot of the process of using Sunshine on SteamOS 3.4, but unfortunately there are still a lot of other factors that make the steps very complicated to explain. Due to growing project sizes, when I use the techniques I show here, the default size of the SteamOS root partition is now too small to accommodate all the dependencies at once, so I've just been making space by deleting folders like /usr/share/doc, /usr/share/man and /usr/share/wallpapers, uninstalling build-only dependencies after using them, and removing preinstalled packages I don't use, rotating through free space in this way until Sunshine is completely installed. I obviously knew this would eventually happen to the way I use SteamOS, but I'm still not sure what my preferred solution will be when I completely run out of the space I need. You are welcome to try out ValShaped's rwfus, but I don't think I will cover that in this guide. My general plan, which I have tested working for past SteamOS releases, has been something like this:

  • Boot a live distro image via USB
  • Use dd , nc , gzip and md5sum in a convoluted construction to disk clone backup the entire Steam Deck boot drive to a NAS over wifi, then verify its integrity
  • Use gparted to resize the /home partiton to be smaller and the / partiton to be bigger
  • Rely on gparted to automatically align the partitions and resize their filesystems
  • Reboot into resized SteamOS and use new space as desired
  • Whenever I want to install a Steam Deck OS Update, perform the dd backup process again
  • Erase the boot drive
  • Completely reinstall SteamOS from the Valve recovery image
  • Update it to the version I want
  • Perform the resize process again
  • Extract and mount the image backup on the NAS
  • And finally copy all my desired files from the NAS back to the Steam Deck

Obviously this is really undesirable for most, but it doesn't personally bother me too much. I will keep thinking about all this though, and whether there is any other way I would consider for this guide in the future.

@andres-asm
Copy link

I just compiled your repository (using my build process rather than a Flatpak) and:

* I can see your print statements in the Sunshine log

* The changes you applied are correctly working around the issue shown in your screenshot (entire viewport visible in Moonlight)

For this reason, I suspect your source code might not be the source of the Flatpak you are using. I recommend you first verify that the print statements you added are showing up in your Sunshine log. If they are, then the only remaining explanation is that, bizarrely, this fix I came up with somehow only works on native builds and not Flatpak builds, and I can't imagine why.

Yeah I see the printfs on the log which is why I was so puzzled...

@robertkirkman
Copy link
Author

I just compiled your repository (using my build process rather than a Flatpak) and:

* I can see your print statements in the Sunshine log

* The changes you applied are correctly working around the issue shown in your screenshot (entire viewport visible in Moonlight)

For this reason, I suspect your source code might not be the source of the Flatpak you are using. I recommend you first verify that the print statements you added are showing up in your Sunshine log. If they are, then the only remaining explanation is that, bizarrely, this fix I came up with somehow only works on native builds and not Flatpak builds, and I can't imagine why.

Yeah I see the printfs on the log which is why I was so puzzled...

The only thing I can think of to try is if you run the same test that you did to produce the screenshot you showed, except instead with the official Sunshine Flatpak, unpatched, and check whether it looks the same. If it looks better, then your Steam Deck might be a different hardware revision I don't know about, but if you already checked and it looks the same, then I have no idea why this patch doesn't help you, I am really sorry

@andres-asm
Copy link

no worries! I will try your method eventually

@robertkirkman
Copy link
Author

Good news, Valve has just fixed the encoding issue, and recompiling mesa is no longer required on SteamOS 3.4! You just need to grab Valve's fixed mesa packages using sudo pacman -Syyu ; if you have the correct /etc/pacman.conf, they will be downloaded from jupiter-main. This reduces the dependency count substantially.

@rondhi
Copy link

rondhi commented Dec 25, 2022

Gotta thank you for this tutorial. It helped me to figure out how to capture games in gaming mode using obs-vkcapture. I even wrote a tutorial and cited your tutorial. I assume that your method also captures non-OpenGL/non-Vulkan games, though, which is the drawback of obs-vkcapture. Happy holidays!

@safijari
Copy link

safijari commented Jan 4, 2023

Good news, Valve has just fixed the encoding issue, and recompiling mesa is no longer required on SteamOS 3.4! You just need to grab Valve's fixed mesa packages using sudo pacman -Syyu ; if you have the correct /etc/pacman.conf, they will be downloaded from jupiter-main. This reduces the dependency count substantially.

I just tried all of your instructions on 3.4.4. This is after Valve fixed the encoding/decoding issue. I didn't have to do anything with mesa and was able to get sunshine built and working.

Your patch seems to already be part of sunshine now but using Sunshine from the official builds (I used appimage) would not start a KMS grab, and just give a black screen instead (you can still see and control the mouse but that's all). I did the setcap thing too but no dice. Any ideas as to why that might be happening?

@lyndonguitar
Copy link

is there a way to automatically run it in gaming mode?

@andres-asm
Copy link

how are you starting it now?

@faders111
Copy link

my steam deck bricked after i restarted after step 5. rip

@robertkirkman
Copy link
Author

my steam deck bricked after i restarted after step 5. rip

Might not necessarily be bricked! I'm really sorry, like any disabled-readonly guide this got a bit outdated and I'm aware it can mess up current SteamOS versions as it's currently written. But please try this to get booted without having to reinstall!

  1. Shut off Steam Deck completely
  2. Hold the ・・・ button and then while holding down the ・・・ button, press and release the Power Button, then release the ・・・ button after you hear the POST noise
  3. You should see this
    image
    Pick one of the "B" options, and if you still can't boot, try the "A" option. In my experience, the "A" option was the one that got corrupted for me
  4. After booting successfully this way, everything returned to normal on subsequent boots, and I believe that installing official updates from Valve eventually erases the corrupted backup filesystem and replaces it with a clean one.

I'm very sorry to say that I did actually realize my steps began corrupting recent SteamOS versions, because I did experience that, but I neglected to edit this page with a warning because I quickly worked around the issue without thinking about it too much and I forgot that it could easily ruin someone else's experience. A large piece of this guide has been upstreamed into official sunshine since the time I wrote this, so this guide needs heavy revision anyway. One day I will write more revisions to this, I just don't have time to right now. I hope this advice helps you avoid fully reinstalling your SteamOS

@faders111
Copy link

faders111 commented Jul 31, 2023 via email

@robertkirkman
Copy link
Author

Gotta thank you for this tutorial. It helped me to figure out how to capture games in gaming mode using obs-vkcapture. I even wrote a tutorial and cited your tutorial. I assume that your method also captures non-OpenGL/non-Vulkan games, though, which is the drawback of obs-vkcapture. Happy holidays!

Wow, thank you for making that, while updating my guide I added a link to your guide in my guide too.

@andres-asm
Copy link

In case this is not widely known, there is a decky loader plugin already that supports video recording

@robertkirkman
Copy link
Author

In case this is not widely known, there is a decky loader plugin already that supports video recording

Thanks I added a link to that too. The truth is, while this guide was the first ever example of recording the Gaming Mode screen immediately after SteamOS 3 released in 2022, it evolved into primarily:

  • my personal disabled-read-only technique
  • specifically Sunshine Stream for SteamOS Gaming Mode, which is the streaming method I usually use because of its game netplay (gamepad input) and remote desktop (keyboard and mouse input) features, and which is open source unlike Steam Remote Play

While that was happening, many other people created their own methods to suit their needs, including the one you mentioned, and I think it might be good for me to just link some of them this way so that people can easily find the method that has all the features they need.

@rondhi
Copy link

rondhi commented Aug 23, 2023

@robertkirkman Hey thanks for linking my guide! I haven't updated my guide in a while so I don't know if it still works, but in the comments on my gist, someone came up with an easy way to capture the screen using the flatpack OBS Studio and gstreamer obs plugin. It's super easy to set up since you don't even need to touch the command line.

@s0th1s
Copy link

s0th1s commented Mar 3, 2024

I just wanted to clarify what the setcap command is for "(which sunshine )". What is it supposed to be set to?

  1. Enable DRM capture mode in sunshine
    sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))

@robertkirkman
Copy link
Author

robertkirkman commented Mar 4, 2024

I just wanted to clarify what the setcap command is for "(which sunshine )". What is it supposed to be set to?

2. Enable DRM capture mode in sunshine
   sudo setcap cap_sys_admin+p (readlink−f(which sunshine))

If I understand your question correctly: for me, that command is exactly equivalent to this one:

sudo setcap cap_sys_admin+p /usr/bin/sunshine-0.21.0

If you try to use this version of the command and it says /usr/bin/sunshine-0.21.0 is not found, then you would have a different version of sunshine from the one this page currently gives, and would need to figure out a way to apply the same operation to your version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment