把 Arch 变成假 SteamOS

为什么这次更的这么快? 总之绝对不是上一篇写的太烂, 导致自己都看不下去了.

明明是一篇简单的基础教程, 但是却用了那么多只有老 Pythoner 才会的高级功能, 看不懂才是正常的. 光顾着赶进度了, 完全没考虑看不看得懂这回事了, 太失败了.

既然如此, 那也只有疑似谢罪了, 下辈子要再来看我发电啊.

呆——喵——

所以这次就不更新下篇了, 等我先把上篇重置了再说. (欸嘿, 又可以水一篇)

唉, 炒冷饭... 唉.

unknown title
unknown artist
0:00

p😢q

TL; DR

printf << 'EOF' > /usr/local/share/wayland-sessions/steam-gamescope.desktop
[Desktop Entry]
Name=Steam Big Picture (Gamescope)
Comment=Start Steam Big Picture in Gamescope
Exec=/usr/bin/gamescope --backend drm --steam -- /usr/bin/steam -gamepadui
TryExec=/usr/bin/gamescope
Type=Application
DesktopNames=Gamescope
EOF

好, 此文完结, 打游戏去了, 掰掰

起因

因为我的电脑只有可怜的 6G 显存, 导致他在运行一些游戏的时候可能出现显存不够用的情况, 继而导致各种各样的问题, 也就是常说的 "爆显存" 了.

虽说 "爆显存" 有时候并不会导致游戏直接崩溃, 在轻微显存溢出的时候显卡驱动会暂时降级某些优先级比较低的资源, 把这些资源通过与主板相连的 PCIe 接口转移到系统内存里来避免直接崩溃.

但是呢, 这又带来了一些其他的问题.

插在主板上的内存条 (System RAM) 主要是服务于 CPU 的, 因为现代 CPU 的频率相当吓人, 为了不拖累 CPU 的速度, 他们都是专门为延迟优化的 (CPU 内部的 LX 缓存也是为此而生的);

而显存 (VRAM) 是服务于 GPU 的, 与 CPU 相比, 他的显著区别是, GPU 的计算单元 (ALU) 更加简单, 没有 CPU 复杂的乱序执行, 分支预测, 和各种指令集架构的支持. 这些计算单元只能进行简单的计算, 但是也正因为简单, GPU 内可以一次性集成成千上万个计算单元 (一般的民用 CPU 大概只有十核左右), 为了让每个 GPU 可以充分运转, 就需要比 CPU 高的多的带宽来传输数据. (不然就会导致一核有难, 千核围观的奇观)

RAM与VRAM

那么这个差距有多大呢? 我们可以自己计算一下, 计算公式如下:

理论带宽(GB/s)=传输速率(MT/s)×位宽(Bit)8\text{理论带宽}(GB/s)=\frac{传输速率(MT/s) \times 位宽(Bit)}{8}

以我的电脑为例, 内存的传输速率是 3200MT/s3200MT/s, 位宽是 64Bit64Bit, 因为插了两条组成了双通道, 还需要乘以二, 计算结果如下:

python -c 'print(3200*64*2/8/1000)'
51.2

可以看到我的系统内存的带宽是 51.2GB/s51.2GB/s, 如果要换算成二进制的化大概就是 48.8GiB/s48.8GiB/s :

python -c 'print(51.2*1000**2/1024**2)'
48.828125

为什么要用 Python 来算数? 因为我的电脑没装计算器, 并且系统自带的 bc 也不会用. 感觉现在新接触 Linux 的人好像也没多少人会用这个老古董.

那么显存呢, 以一张 "普普通通的过气亮机卡" RTX4090 为例, 他的计算核心有一万六千多个, 为了让这些核心充分运转, 他的显存带宽大概有 1TB/s1TB/s.

扯远了, 总之轻度的炸显存会导致游戏帧率骤降, 比如说 DOOM: The Dark Ages, 他就要求 8G 的显存, 但是我依旧可以在 1080p 低画质下正常游玩, 只不过在某些地图需要关掉 Plasma shell (桌面环境) 才不会卡顿.

既然连这个都要关掉, 那么为什么不直接使用一个更加轻量化的桌面环境呢?

所以, 参考 SteamOS, 可以在打游戏的时候使用一个专门为游戏而生的轻量化环境: gamescope

SteamOS 与 Arch 的差异

神经元激活

众所周知, SteamOS 是 V 社 (Valve) 为了自家的游戏设备而退出的系统, 最早出现在 Valve 的 Steam Deck 掌机上, 后续也开放了通用 PC 的支持, 可以在自己的 X86 电脑上安装这个系统, Steam 官方的说明: Steam Support :: SteamOS Installation and Repair.

正因如此, 它天生就是一个为了商业化而生的系统. 但是他使用的基座系统, Arch Linux 却是一个社区驱动的滚动发行版, 他的稳定性全部来源于社区的相互协作, 其中的任意一个环节出现了什么问题都会影响到终端用户. (你也不想你的游戏机在某次更新之后就再也开不了机了吧? 在 Arch 社区里这个情况俗称 "滚挂了")

作为一个商业化的系统, 这种不确定性因素是不可接受的. 所以虽然 SteamOS 确实是基于 Arch, 但是从理念上就已经不同了.

具体来说, SteamOS 被设计成一个 "不可变系统", 他的根目录是只读的, 所有的数据都存在 /home 目录下; 并且还引入了类似 Android 设备的 A/B 镜像更新, 即使使用 ROOT 权限更改了系统, 在下次系统更新后也会被全部还原. 这样做虽然稳定是稳定了, 但是他如果要做为一个日常使用的桌面系统来说还是有点限制太大了. (不过真的有人这么用游戏机吗?)

配置

为您效劳

没有 steam 的 proton 都不知道要怎么在 Linux 上打游戏了

好像扯远了, 总之, 我们可以在 Arch 上通过 SteamOS 同款的 gamescope + steam 大屏幕模式来得到一个类似于 SteamOS 的东西. (所以说是 "假 SteamOS") 同时因为这样启动的组件都更加轻量化了, 游戏的帧率可能会稍微高一点. (当然, 也就一点, 正常玩几乎分辨不出来, 并且还有 bug, 比如说在 N 卡下某些情况会导致花屏, 我怀疑是 steam 客户端的 electron 导致的问题, 但是因为他是闭源的也就无从查证了. 在这个时候你知道我要说什么的)

首先, 需要安装 gamescope 和 steam:

sudo pacman -S gamescope steam

根据你的显示管理器来配置启动 gamescope 桌面环境的方式, 比如说我使用的是 SDDM, 那么就需要在 /usr/local/share/wayland-sessions/ (~/.local/share/wayland-sessions/ 也行) 这个目录下加入 gamescope 的启动配置.

[Desktop Entry]
Name=Steam Big Picture
Comment=Start Steam Big Picture
Exec=/usr/bin/gamescope --backend drm --steam -- /usr/bin/steam -gamepadui
TryExec=/usr/bin/gamescope
Type=Application
DesktopNames=Gamescope

上面最主要的就是 Exec=... 这一行, --backend drm 告诉 gamescope 直接控制输出, --steam 启用 gamescope 的 steam 集成功能; 后面的双横线告诉 gamescope 要启动哪个程序, -gamepadui 就是使用大屏幕模式启动 steam. (想要在常规的桌面环境快速启动 steam 大屏幕模式也是可以直接使用 steam -gamepadui 这个命令)

加上之后重新注销进入 SDDM, 在左下角就可以看到一个新的 "Steam Big Picture" 选项了, 登录之后就可以直接进入 steam 大屏幕模式. 不过用过大屏幕模式的应该都知道, 这个模式是专门为手柄设计的, 用键鼠的话操控可能会比较困难, 如果不用手柄的话还是比较推荐正常的 steam 桌面 UI. (现在说是不是有点晚?)

那么这个 gamescope 作为一个游戏专用的环境有哪些优化呢? 我又让 AI 分析了一下, 大概可以总结为: 1. 缩短提交路径, 降低硬件延迟并适配 Proton; 2. 调整帧节奏, 改善帧间隔的稳定性. (有问题别问我啊, 我也不懂)

好处说完了, 哪坏处呢?

首先就是他作为一个桌面环境, 跟很多的通用桌面环境的交互逻辑是不一样的, 在用的时候可能会有各种各样奇奇怪怪的问题. 比如说 fs 社的游戏, 黑魂和法环, 他们在游戏里点击手柄中间的 "徽标键" (我也不知道这个叫什么, steam 管他叫 steam 键, xbox 管他叫 xbox 键, 总之就是中间的那个键) 唤出 steam 界面的时候, 使用的还是桌面环境的逻辑, 因为失去了窗口焦点, 他们都会自动最小化; 然后呢, 画面就只有最左上角有一点点了. (所以我甚至不能切出去调音量了, 太坏了, 让我这样玩游戏, 你很开心吗?)

少女的脸红胜过一切言语

如果你去翻的话, 就会发现 gamescope 里还有针对某个游戏的专门修复, 大部分都是对类似于上面这类问题的修复. (比如说甚至还翻出了 Baldr Sky)

还有一个小问题是关于多媒体键的, 按照我平时的习惯, 我一般会在手柄的扩展键上绑定一个调节音量的功能. 但是上面的配置是没有这个功能的, 如果需要的话可以使用下面的这个补丁重新编译 gamescope, 经过我的测试, 在现在最新的 0e590c755e79c23607378495d10ceb4308b01a59 这次的提交上是正常的.

diff --git a/src/wlserver.cpp b/src/wlserver.cpp
index 3d7d123c..8bb1b87e 100644
--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -305,6 +305,12 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
 	// TODO: Remove the below hack when Steam is shipping
 	// `gamescope_action_binding_manager` in Steam Stable
 	// as it can just use a keybind to grab these always.
+	if ( wlserver_process_hotkeys( keyboard, event->keycode, event->state == WL_KEYBOARD_KEY_STATE_PRESSED ) )
+	{
+		bump_input_counter();
+		return;
+	}
+
 	bool forbidden_key =
 		keysym == XKB_KEY_XF86AudioLowerVolume ||
 		keysym == XKB_KEY_XF86AudioRaiseVolume ||
@@ -328,11 +334,8 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
 		}
 	}

-	if ( !wlserver_process_hotkeys( keyboard, event->keycode, event->state == WL_KEYBOARD_KEY_STATE_PRESSED ) )
-	{
-		wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard );
-		wlr_seat_keyboard_notify_key( wlserver.wlr.seat, event->time_msec, event->keycode, event->state );
-	}
+	wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard );
+	wlr_seat_keyboard_notify_key( wlserver.wlr.seat, event->time_msec, event->keycode, event->state );

 	bump_input_counter();
 }

这个补丁把音量键的处理放到前面, 避免被提前返回. 对应的配置也要改成:

[Desktop Entry]
Name=Steam Big Picture
Comment=Start Steam Big Picture
Exec=/usr/bin/env STEAM_ENABLE_VOLUME_HANDLER=1 /usr/bin/gamescope --backend drm -- --steam -- /usr/bin/steam -gamepadui -steamos
TryExec=/usr/bin/gamescope
Type=Application
DesktopNames=Gamescope

多了 STEAM_ENABLE_VOLUME_HANDLER 的环境变量和 -steamos 的启动选项. (所以 SteamOS 上的 steam 客户端竟然不是特供的吗?)

具体的配置可以去翻我的 dotfiles, 我等等会把他整理好上传上去. (为什么我的 dotfiles 怎么这么空? 因为很多的配置都是默认的, 上传了也没什么用) 并且我的 dotfiles 也是模块化的, 高内聚低耦合, 感觉像是写代码走火入魔了.

哦, 还有一点忘记说了, steam 的大屏幕模式可能会因为网络不畅导致一直转圈, 有时候需要先启动网络代理接管 steam 的流量才行.


"正因如此, 是艾尔登法环的时候了." (君の交界地语 is not good)

"你们玩老头环的不能在过场动画穿得稍微像个人吗"

🌷

最近为了玩月光大剑 (老婆剑) 还特地去洗点变成智力流了, 看什么, 没见过扛大剑的法师? 以后出去别说我认识你们这群智力⑨的艾尔登之王(.

“Ah, you were at my side all along.”

“My true mentor... My guiding moonlight...”

"啊, 原来你一直与我同在." (高举月光大剑)

(出自 fs 社的《血源诅咒》, 这个游戏至今都没有 PC 版本, 天下苦索尼久矣)

原来你一直与我同在

关于可怜的菈妮认为自己没有阿褪高,显得很没有威严,于是每次见面前都要悄悄垫几本书这件事

四手蓝皮怪(划死)

猫猫虫菈妮


恋と魔法のティーパーティー

美味犬娘, prpr