GPU 直通渲染验证测试报告(v0.9.3)

August 23, 2026 · View on GitHub

2026-08-21 · 验证"GPU 直通"方案能否解决 llvmpipe 软件渲染的帧率瓶颈, 使离屏渲染(rviz_offscreen_node)在 30 Hz 请求下真正达到 30 Hz。


1. 测试目标

  • 前提:v0.9.2 已把 llvmpipe 下 30 Hz 请求的帧率从 11.1 提升到 ~22 Hz (消除双重渲染),瓶颈为 llvmpipe 软件光栅化(renderOneFrame 27–31ms/帧)。
  • 本测试验证:NVIDIA GPU 直通能否消除该瓶颈、达到 30 Hz,并评估链路开销。

2. 硬件与环境

GPUNVIDIA GeForce RTX 4060 Ti 16GB(PCIe)
驱动595.71.05(open kernel module;nvidia_drm/nvidia_uvm 已加载)
DRM 节点/dev/dri/card1/dev/dri/renderD128(本用户不在 video/render 组,测试期用 sudo 临时 chmod o+rw,测后恢复)
NVIDIA 节点/dev/nvidia{0,ctl,modeset,uvm}(666,无需额外权限)
X serverXorg :1(GDM 启动,加载 nvidia_drv.so + libglxserver_nvidia.so,GLX 1.4 + NV-GLX/NV-CONTROL)
软件渲染对照Xvfb + Mesa llvmpipe(v0.9.2 基线)
测试场景lite_urdf 低模(38.7 万面,open3d),1000×750,rate=30

3. 链路与排查过程

3.1 逐环节分析(回答"GPU 直通是否增加链路开支")

环节llvmpipeGPU 直通变化
渲染 renderOneFrame27–31 ms~9 ms大幅下降
像素获取 copyContentsToMemory1–2 ms1–2 ms(GPU→CPU 回读,2.25MB 量级)基本持平
发布 / 桥接 / VLM不变不变无变化

结论:GPU 直通不增加链路开支,净节省 ~20 ms/帧;唯一新增的 GPU→CPU 回读(~1–2 ms)远小于渲染节省量。

3.2 排查中发现的三层阻塞(均已解决)

  1. nvidia-smi NVML 失败Unknown Error)——驱动用户态工具异常,但 GL/GLX 实测可用(以实际渲染结果为准,工具失败不影响功能);
  2. /dev/dri/renderD128 权限拒绝——当前用户不在 video/render 组, Mesa/EGL 的 DRM 路径打不开;用 sudo 临时 chmod o+rw 解决(测试用, 重启/udev 重置后失效);
  3. OGRE GLX context 创建失败BadValue,100 次重试后 abort)——定位为:
    • rviz 默认 FSAA=4use_anti_aliasing_)→ OGRE selectFBConfig 的 maxAttribs 优化选中 32-bit ARGB visual 的 fbconfig;
    • NVIDIA GLX 拒绝在 32-bit visual 窗口上创建 GL 3.0 core context (实测枚举 215 个 fbconfig:仅 24-bit / samples=0 的配置可创建,32-bit 全部 BadValue);
    • 修复rviz_rendering::RenderSystem::disableAntiAliasing()(离屏渲染无 AA 视觉损失)→ OGRE 回落到 24-bit 配置 → context 创建成功。

4. 测试结果

4.1 帧率对比(1000×750,lite_urdf 低模 38.7 万面,rate=30)

指标llvmpipe(v0.9.2)NVIDIA GPU(v0.9.3)提升
静止稳态帧率21.5–22.9 Hz30.0 Hz(满 rate)+31%
运动稳态帧率21.5 Hz30.0 Hz(满 rate)+40%
onUpdate(含渲染)~30 ms~9 ms3.3×
每帧循环~47 ms33 ms(sleep 22ms 富余)
测量帧数400+535 / 540

4.2 画面正确性

  • GPU 渲染画面与 llvmpipe 基准一致(fg 75849 vs 73331,red/orange 等彩色部件 完整;微小差异来自 AA 关闭的边缘);运动帧差异 24335 px(双臂区域)——动作 渲染流畅
  • 10 Hz 请求回归:仍达上限(未测,逻辑同上——onUpdate 9ms 远小于 100ms sleep)。

4.3 回归

  • llvmpipe(Xvfb)回归disableAntiAliasing 后 22.4 Hz、画面正确—— 无劣化(AA 关闭对离屏渲染无视觉影响,CPU 渲染反而略快)。

5. 结论

  1. GPU 直通方案有效且不增加链路开支:30 Hz 请求从 llvmpipe 的 ~22 Hz 提升到 30.0 Hz(满 rate),onUpdate(渲染)30 → 9 ms,且有 22 ms/帧 富余可支撑更高分辨率/面数;
  2. 实现方式:Xorg(NVIDIA GLX)+ 现有 rviz_offscreen_node,仅需 disableAntiAliasing()offscreen/src/rviz_offscreen_node.cpp)绕过 NVIDIA 的 32-bit visual GLX 限制;无需 EGL 无头改造;
  3. 前置条件:GPU 驱动正常 + 用户可访问 /dev/dri(或 X 已在 NVIDIA GLX 上运行);启动时 DISPLAY=<NVIDIA X>(如 :1)+ 对应 XAUTHORITY不要用 Xvfb(Xvfb 无 GPU 加速,自动回落 llvmpipe);
  4. 可选后续:EGL surfaceless(已验证 NVIDIA EGL 1.5 可用)可去掉 X 依赖, 但需 OGRE 渲染目标改造,收益仅为省掉 X 层(当前 X 层开销已包含在 9ms 内, 优先级低)。

6. 使用方式(GPU 渲染)

# 前置:NVIDIA 驱动 + Xorg 已用 NVIDIA GLX(无 Xvfb)
export DISPLAY=:1 XAUTHORITY=/run/user/1000/gdm/Xauthority   # 视环境调整
ros2 run dsh_ros2_rviz_offscreen rviz_offscreen_node \
  --ros-args -p config_path:=/tmp/robot_scene_lite7.rviz \
  -p topic:=/rviz/scene -p width:=1000 -p height:=750 -p rate:=30.0
# 节点日志 onupdate≈9ms 即 GPU 生效;≈30ms 则为 llvmpipe(检查 DISPLAY)

7. 相关代码

  • offscreen/src/rviz_offscreen_node.cppRenderSystem::disableAntiAliasing()(v0.9.3)
  • 其余优化(低模 mesh、直读像素、双重渲染消除):docs/architecture.md §5、docs/test-robot-state-vision.md §8