Skip to content

Commit 5f43eb9

Browse files
committed
feat(yui): Add sunshine streaming
1 parent 3adecad commit 5f43eb9

7 files changed

Lines changed: 217 additions & 3 deletions

File tree

home-config/dotfiles/sway.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ output "Dell Inc. DELL G2723HN 5B0C3H3" {
1515
max_render_time 3
1616
}
1717

18+
output "GSS edid.build 0x00000001" disable
19+
1820
# Window decorations
1921

2022
client.focused $lavender $base $text $lavender $lavender

nixos-config/desktop/greeter/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ let
1111

1212
sway-gtkgreet = pkgs.writeText "sway-gtkgreet" ''
1313
output '*' background #fafafa solid_color
14+
output 'GSS edid.build 0x00000001' disable
1415
seat seat0 xcursor_theme Bibata-Original-Ice 24
1516
1617
exec dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK

nixos-config/hosts/yui/default.nix

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{ pkgs, flake-inputs, ... }:
1+
{ lib, flake-inputs, ... }:
22
{
33
imports = [
44
flake-inputs.disko.nixosModules.disko
@@ -19,15 +19,21 @@
1919

2020
nixpkgs.config.allowUnfreePredicate =
2121
pkg:
22-
builtins.elem (pkgs.lib.getName pkg) [
22+
(builtins.elem (lib.getName pkg) [
2323
"steam"
2424
"steam-run"
2525
# Required to get the steam controller to work (i.e., for hardware.steam-hardware)
2626
"steam-original"
2727
"steam-unwrapped"
2828
"nvidia-x11"
2929
"obsidian"
30-
];
30+
# For sunshine streams with nvenc
31+
"cuda-merged"
32+
"libnpp"
33+
])
34+
|| (lib.strings.hasPrefix "cuda_" (lib.getName pkg))
35+
|| (lib.strings.hasPrefix "libcu" (lib.getName pkg))
36+
|| (lib.strings.hasPrefix "libnv" (lib.getName pkg));
3137

3238
home-manager.users.tlater = import "${flake-inputs.self}/home-config/hosts/yui.nix";
3339

nixos-config/hosts/yui/games.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ in
99
nix-gaming.nixosModules.pipewireLowLatency
1010
nix-gaming.nixosModules.platformOptimizations
1111
nix-gaming.nixosModules.wine
12+
13+
./sunshine.nix
1214
];
1315

1416
environment.systemPackages =
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
{
2+
flake-inputs,
3+
config,
4+
pkgs,
5+
...
6+
}:
7+
let
8+
inherit (flake-inputs.self.pkgs-lib.${pkgs.stdenv.hostPlatform.system}) writeNuWith;
9+
inherit (flake-inputs.self.packages.${pkgs.stdenv.hostPlatform.system}) edid-generator;
10+
in
11+
{
12+
nix.settings = {
13+
substituters = [ "https://cache.nixos-cuda.org" ];
14+
trusted-public-keys = [ "cache.nixos-cuda.org:74DUi4Ye579gUqzH4ziL9IyiJBlDpMRn9MBN8oNan9M=" ];
15+
};
16+
17+
# Create a virtual display to render games for sunshine on
18+
hardware.display = {
19+
edid.packages = [
20+
(pkgs.runCommand "VTCL65C825.bin"
21+
{
22+
nativeBuildInputs = [ edid-generator ];
23+
settings = pkgs.writers.writeJSON "edid.json" {
24+
defaultMode = {
25+
width = 1920;
26+
height = 1080;
27+
refresh = 120;
28+
};
29+
modes = [
30+
{
31+
width = 1920;
32+
height = 1080;
33+
refresh = 120;
34+
}
35+
{
36+
width = 1920;
37+
height = 1080;
38+
refresh = 60;
39+
}
40+
{
41+
width = 3840;
42+
height = 2160;
43+
refresh = 120;
44+
}
45+
{
46+
width = 3840;
47+
height = 2160;
48+
refresh = 60;
49+
}
50+
];
51+
audio = false;
52+
hdr = true;
53+
deepColor = true;
54+
dsc = false;
55+
vrr = false;
56+
listedModesOnly = false;
57+
};
58+
}
59+
''
60+
mkdir -p "$out/lib/firmware/edid"
61+
edid-generator $settings > "$out/lib/firmware/edid/VTCL65C825.bin"
62+
''
63+
)
64+
];
65+
66+
# The port (DP-2) to be used must be free on the GPU, use
67+
# `ls /sys/class/drm/*/status` to find free ports.
68+
#
69+
# Using DP-2 because HDMI doesn't support 3840x2160@120.
70+
outputs."DP-2" = {
71+
edid = "VTCL65C825.bin";
72+
mode = "e";
73+
};
74+
};
75+
76+
services.sunshine = {
77+
enable = true;
78+
package = pkgs.sunshine.override { cudaSupport = true; };
79+
80+
openFirewall = true;
81+
settings = {
82+
sunshine_name = config.networking.hostName;
83+
system_tray = false;
84+
encoder = "nvenc";
85+
86+
# TODO(tlater): Switch to portalgrab once released:
87+
# https://github.com/LizardByte/Sunshine/pull/4417
88+
capture = "wlr";
89+
output_name = 1;
90+
};
91+
92+
applications.apps = [
93+
(
94+
let
95+
runScript = writeNuWith {
96+
packages = [
97+
pkgs.util-linux
98+
config.programs.sway.package
99+
config.programs.steam.package
100+
];
101+
};
102+
in
103+
{
104+
name = "Steam Big Picture";
105+
cmd =
106+
(runScript "run-steam" /* nu */ ''
107+
swaymsg output DP-2 enable
108+
swaymsg workspace sunshine gaps outer 0
109+
swaymsg workspace sunshine gaps inner 0
110+
swaymsg workspace sunshine output DP-2
111+
swaymsg focus output DP-2
112+
swaymsg assign '[title="Steam Big Picture Mode"]' → workspace steam
113+
114+
try {
115+
setsid steam steam://open/bigpicture
116+
}
117+
'').outPath;
118+
119+
auto-detach = false;
120+
prep-cmd = [
121+
{
122+
undo =
123+
(runScript "close-steam" /* nu */ ''
124+
swaymsg output DP-2 disable
125+
126+
sleep 5sec
127+
if (ps | where pid == (cat ~/.steampid)) != [ ] {
128+
try {
129+
steam -shutdown
130+
}
131+
}
132+
'').outPath;
133+
}
134+
];
135+
}
136+
)
137+
];
138+
};
139+
140+
}

pkgs/packages/custom-edid.nix

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
runCommand,
3+
xorg,
4+
edid-generator,
5+
}:
6+
edid-generator.overrideAttrs (old: {
7+
# passAsFile = [ ];
8+
clean = true;
9+
10+
# modelines = ''Modeline "3840x2160" 712.34 3840 4152 4576 5312 2160 2161 2164 2235 -HSync +Vsync'';
11+
12+
modelinesPath =
13+
(runCommand "modelines" { nativeBuildInputs = [ xorg.xorgserver ]; } ''
14+
gtf 3840 2160 120 > modeline
15+
sed -i 's/"3840x2160_120.00"/"VTCL65C825"/' modeline
16+
grep -v '# ' modeline > $out
17+
'').outPath;
18+
})

pkgs/packages/edid-generator.nix

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
fetchFromGitHub,
3+
runCommand,
4+
writers,
5+
}:
6+
let
7+
edid-core =
8+
runCommand "edid-core"
9+
{
10+
src = fetchFromGitHub {
11+
owner = "goncalossilva";
12+
repo = "edid-generator";
13+
rev = "bc311cb7d5d4900a1bdad8fa967125c8e50c0174";
14+
hash = "sha256-90yzP0wxVms/6+sLa8zOkZbuBkqnBMQS0WyEn2poWUM=";
15+
};
16+
}
17+
/* sh */ ''
18+
mkdir -p "$out/lib/node_modules/edid-core/"
19+
cp "$src/assets/js/edid-core.js" "$out/lib/node_modules/edid-core/index.js"
20+
'';
21+
in
22+
writers.writeJSBin "edid-generator" { libraries = [ edid-core ]; } /* js */ ''
23+
const { readFile } = require("node:fs/promises");
24+
const { resolve } = require("node:path");
25+
const { stdout, stderr } = require("node:process");
26+
27+
const { generateEdid } = require("edid-core");
28+
29+
async function main() {
30+
const settings = JSON.parse(await readFile(resolve(process.argv[2])));
31+
const edid = generateEdid(settings);
32+
33+
if (edid.warnings) {
34+
console.warn("EDID wasn't generated cleanly:");
35+
36+
for (warning of edid.warnings) {
37+
console.warn("- " + warning);
38+
}
39+
}
40+
41+
stdout.write(edid.bytes);
42+
}
43+
44+
main();
45+
''

0 commit comments

Comments
 (0)