【教程】VisionFive 2 上跑 Xonotic:让 PowerVR 真正硬件加速(附 deb,apt 装完即玩)

这周心血来潮,想在开发板上玩Xonotic。在官方 Ubuntu 24.04 镜像的 VisionFive 2
上,Xonotic 0.8.6 可以稳定跑在PowerVR B-Series BXE-4-32 的硬件 OpenGL ES
3.2
上。这篇文章记录完整的踩坑过程,并给出一个打包好的 deb。

一、成果

  • 1080p 全屏硬件 GLES 基准(glmark2-es2)430 FPS
  • 单人 CTF + 2 机器人约 40 FPS
  • 进图后 GPU 利用率只有 28–36%,真正的瓶颈在 CPU 单核(原因见第四节)

游戏内截图

截图 1:游戏内画面(1080p 全屏,CTF)

二、原理:VF2 的 GPU 只认 OpenGL ES

VisionFive 2 的驱动栈会暴露两个 EGL 设备:

EGL 设备 支持的客户端 API 渲染器
pvr(硬件) 只有 OpenGL_ES PowerVR B-Series BXE-4-32 (GLES 3.2)
swrast(兜底) OpenGL + OpenGL_ES softpipe

由此有两个结论:

  1. 桌面 OpenGL 程序会静默降级到软件渲染,帧率会掉,且屏幕上不会有
    报错
  2. X11 / Xwayland 也会降级。实测同一份引擎:X11 下 GL_RENDERER 是
    softpipe,只有原生 Wayland 会话才能拿到 PowerVR。

验证命令:

eglinfo | grep "OpenGL ES profile renderer"
# 正确输出: OpenGL ES profile renderer: PowerVR B-Series BXE-4-32
ls /dev/dri/          # 必须能看到 renderD128

eglinfo 输出

截图 2:终端里 eglinfo 显示 PowerVR B-Series BXE-4-32

三、三个坑

坑 1:apt 升级导致 GPU 固件丢失,整个桌面变卡

pvrsrvkm(PowerVR 驱动)是内核内置的,启动早期 probe —— 那时
根文件系统还没挂载,所以固件 rgx.fw/rgx.sh 必须由 initramfs 提供。

StarFive 原厂 initramfs 是定制打包的(含固件),但只要任何 apt 操作触发了
initramfs-tools 重新生成,固件就会丢。重启后:

pvrsrvkm 18000000.gpu: Direct firmware load for rgx.fw.36.50.54.182 failed with error -2
PVR_K:(Fatal): All RGX Firmware image loads failed ... (PVRSRV_ERROR_NOT_FOUND)
[drm:pvr_drm_load] *ERROR* device initialisation failed (err=-19)

/dev/dri/renderD128 消失,整个 GNOME 桌面退化成 softpipe 软件渲染。
本次 deb 里带了一个 hook(/etc/initramfs-tools/hooks/pvr-rogue-firmware)
自动防住它。如果不小心中招,可以不重启救回:

sudo sh -c 'echo 18000000.gpu > /sys/bus/platform/drivers/pvrsrvkm/bind'

坑 2:菜单的联网检查会卡住加载

Xonotic 菜单启动时会请求 https://update.xonotic.org/checkupdate.txt。在
国际链路较慢的网络下,这个请求会长时间挂在"Still in queue",加载画面就一直
停在那里
:

Downloading https://update.xonotic.org/checkupdate.txt ... ???.?% @ 0.0 KiB/s
Still in queue: https://update.xonotic.org/checkupdate.txt

加载卡在联网检查

截图 3:加载画面卡在 update.xonotic.org 的请求上

本地单人游戏根本不需要它,直接黑洞掉域名即可(立即失败而不是挂起):

echo "127.0.0.1 update.xonotic.org" | sudo tee -a /etc/hosts

坑 3:贴图分辨率不是免费的

PowerVR 驱动不提供 S3TC/DXT 压缩纹理,引擎只能用 CPU 软件解码所有 DDS
贴图(日志里会刷 fake software decoding of compressed texture ...)。于是
进图时间对贴图分辨率敏感:

配置 进图时间(ctf/boil, 1080p)
gl_picmip 3 + 不加载光照贴图(默认) 相对最快
gl_picmip 3 + 烘焙光照贴图 明显更慢(实测超过 12 分钟)
gl_picmip 2 + 烘焙光照贴图 更慢

所以默认配置刻意保持"快"的贴图设置;想折腾画面的可以用包里附带的
quality.cfg。

四、性能实测:为什么是 40 帧

分辨率 GPU 利用率 CPU
800×600 12%(3D 仅 5–11%) 单核 100%
1920×1080 全屏 28–36% 1.17 核

GPU 远没吃满,瓶颈是 CPU。darkplaces 是单线程引擎(客户端 + 服务端 +
机器人 AI 全在一个线程),这块板是 4×U74 @1.5GHz 顺序核,QuakeC 虚拟机在
RISC-V 上也没有 JIT。

游戏内按 Shift+Esc 打开控制台,可以随时调整:

bot_number 2              # 机器人数量(设 0 可以看纯 GPU 上限)
bot_ai_thinkinterval 0.1  # AI 更新频率,越大越省 CPU
showfps 1                 # 显示帧率

五、安装(三步)

xonotic-gles_0.8.6+gles1_riscv64.deb (1.4 MB)

# 1. 安装 deb(GLES2 引擎 + 启动器 + 两套配置 + 下载器 + 文档)
sudo apt install ./xonotic-gles_0.8.6+gles1_riscv64.deb

# 2. 下载官方游戏数据(约 1.2GB)
xonotic-gles-fetch

# 3. 开玩
xonotic-gles

xonotic-gles-fetch 会从 5 个官方镜像并行拉取。官方镜像对单连接限速约
30KB/s,1.2GB 要十几个小时;用 aria2 多连接 + 多镜像实测能跑到几十 MB/s,
并会用官方 SHA512 校验完整性。

六、包里有什么

路径 说明
/usr/bin/xonotic-gles 启动器:强制 Wayland、自动部署配置到用户目录
/usr/bin/xonotic-gles-fetch 数据下载器(多镜像并行 + SHA512 校验)
/usr/games/xonotic-gles/darkplaces-sdl GLES2 引擎(riscv64)
/usr/share/xonotic-gles/balanced.cfg 默认平衡配置(1080p 全屏 + 机器人 2 个)
/usr/share/xonotic-gles/quality.cfg 可选画质优先配置(注意进图时间)
/usr/share/xonotic-gles/build-engine.sh 自行重新编译的脚本
/etc/initramfs-tools/hooks/pvr-rogue-firmware 防 GPU 固件丢失

七、已知限制

  • 联机:本包引擎未链接 d0_blind_id,本地/机器人对战完全正常,连需要
    玩家 ID 的在线服务器可能受限。
  • 纹理压缩不可用:gl_texturecompression 必须为 0,显存占用偏高;启动时
    的 Expect visual problems 只是提示,不影响运行。
  • 进图较慢:本板纹理靠 CPU 软件解码,加上机器人导航数据,进图需要数分钟。

八、附:自己编译 GLES2 引擎

sudo apt-get install -y build-essential libsdl2-dev libjpeg-turbo8-dev \
    libpng-dev zlib1g-dev libvorbis-dev libogg-dev libcurl4-openssl-dev
cd ~/Xonotic && build-engine.sh

核心参数:

make -f makefile sdl-release -j$(nproc) \
  CFLAGS_EXTRA="-DUSE_GLES2 -DGL_RGBA16F=0x881A -DGL_RGBA32F=0x8814 -DGL_HALF_FLOAT_ARB=0x8D61" \
  SDLCONFIG_UNIXLIBS="-lSDL2 -lGLESv2"

还需要给 source/darkplaces/shader_glsl.h 打两个 GLSL ES 兼容补丁
(脚本已包含):

  1. 上游只为桌面 GLSL130/140 输出 precision highp float;,GLES 下所有未加
    精度限定符的 vec3/float 声明都会编译失败;
  2. #define lightcolor 1 会让 vec3 * 1 触发 GLSL ES 的隐式类型转换错误,
    改成 1.0 即可。

环境:StarFive VisionFive 2 v1.3B / Ubuntu 24.04.3 LTS riscv64 / 内核
6.12.5-starfive / Xonotic 0.8.6(darkplaces 引擎自编译 GLES2 版)
感谢deepseek,很多过程都是它做的


2 Likes