在WSL2中启用显卡硬件加速

近日需要在 Ubuntu 下运行 Gazebo 模拟,但是主力机上装的是 Windows 系统,考虑到各种因素,最终选择了WSL2作为虚拟机平台。 在 WSL2 Ubuntu 上安装ROS、Gazebo和PX4都非常简单,运行上也没有什么大问题,但是性能上比较捉襟见肘。 具体来说,虽然 Gazebo 的平均帧率能够达到60FPS,但是散热风扇转得非常大声,发热非常严重,并且不久之后就会降频,帧率骤降。 运行glxinfo可以发现,渲染设备是llvmpipe,这意味着虚拟机并未调用显卡,而是使用 CPU 进行渲染,因此效率低下。 然而,微软发布的新闻表明,WSL2 虚拟机实际上支持显卡虚拟化,并且可以利用显卡硬件加速。 这表示处于某些原因,虚拟机并不能调用显卡。 为了提升性能,减少CPU风扇的噪音,我决定找出问题所在。

关于 LIBGL_ALWAYS_INDIRECT

首先想到的就是曲线救国的手段: 如果不能利用虚拟机的显卡,可以将渲染任务“托付”给实体机进行。 实际上,X Server 支持这一选项。 通过在服务器上启用“原生 OpenGL”(Native OpenGL, wgl),可以让客户端不执行渲染,而是使用服务端显卡。 如果需要启动这一功能,客户端上需要指定LIBGL_ALWAYS_INDIRECT环境变量。

通过这种方式,glxinfo输出的渲染设备不再是llvmpipe,变为了实体机上的 Intel 核显。

然而,这种方法有诸多局限性。 首先,如果服务端有双显卡,这样难以指定渲染使用的显卡。 其次,由于技术原因,间接渲染支持的OpenGL版本只到了1.6,因此相当多的程序无法正常运行。 不幸的是,Gazebo 正是其中之一。 因此,这一条路走不通。

关于 CUDA

这篇文章中给出了在WSL2上启用CUDA加速的详细步骤。 我的系统达到了对应的版本要求,驱动也是最新的,因此可以启用CUDA。 按照指定的步骤操作之后,在虚拟机中成功启动了CUDA加速。 具体而言,nvidia-smi指令成功输出了当前显卡状态。

然而,glxinfo输出的渲染设备仍然是llvmpipe。 这说明虚拟机依然没有调用独立显卡进行渲染。 我推测这可能和 Ubuntu 没有正确的识别渲染设备有关。 然而我十分缺少这方面的经验,因此陷入一筹莫展之中。

最终解决方案

查看/dev目录,可以发现其中确实有dxg这一设备。 如这篇文章所述,这说明虚拟机成功识别了DirectX渲染设备,只是没有调用。

我认为这可能和驱动更新有关,但是仍然找不到合适的解决方案。 偶然间我在 Github 上看到了这篇 Discussion,其中详细指明了如何检查十分启用了硬件加速。

实际上,这和Mesa驱动有关。 这个驱动直到相当近的版本才提供对 Direct3D 12 的稳定支持。 因此,需要更新Mesa驱动,才能识别/dev/dxg设备。

执行以下 Shell 脚本以更新驱动:

# Mesa 不提供官方的二进制文件,需要添加第三方源
sudo add-apt-repository ppa:kisak/kisak-mesa
sudo apt-get update
sudo apt install libegl-mesa0

之后再执行glxinfo,可以发现llvmpipe已经被替换成实机显卡了。 现在再运行 Gazebo,风扇几乎不转了。

更新时间: