如何在 Windows 10(WSL)下的 Ubuntu 上对 OpenGL 进行故障排除

如何在 Windows 10(WSL)下的 Ubuntu 上对 OpenGL 进行故障排除

我使用 Windows Subsystem for Linux (WSL) 在 Windows 10 上安装了 Ubuntu。我试图让 OpenGL 图形工作。我的最终目标是能够运行需要 OpenGL 的 Robot OS (ROS) 的 Gazebo 模拟器。作为第一步,我试图确保 OpenGL 图形能够正常工作。

根据本教程和许多其他人一样,要运行 ROS 和 Gazebo,我应该安装 VcXsrv 并在禁用“Native OpenGL”选项的情况下运行 X 服务器,所以我这样做了。

我目前遇到的问题是 OpenGL 似乎无法正常工作。我已经安装了 Mesa 实用程序,运行时glxgears我确实看到了图形窗口,但动画非常慢。我估计齿轮的转速约为每分钟 1 转。我可以使用箭头键重新调整齿轮的方向,但更新速度仍然非常慢。(如果这很重要的话,时不时就会出现明显的“跳跃”。)

为了进行比较,我尝试glxgears在 VirtualBox 机器上运行 Ubuntu。令我惊讶的是,它的动画速度要快得多;齿轮大约每 4 秒旋转一次,而使用 WSL 在 Windows 下运行时每 60 秒旋转一次(可能 60 秒,但我失去了耐心)。这是一个很大的惊喜,因为我预计 VirtualBox 会慢得多。

在装有 WSL 的 Windows 上,glxgears据称运行速度非常快——介于 800 到 1700 FPS 之间。在 VirtualBox 中glxgears报告约为 900-1000FPS。

glxgears 和 OpenGL 的版本信息:

xxxx@DESKTOP-8U2MCOG:~$ glxgears -info
GL_RENDERER   = Software Rasterizer
GL_VERSION    = 1.4 (2.1 Mesa 19.2.0-devel (git-cdf42f5eaa))
GL_VENDOR     = Mesa Project
GL_EXTENSIONS = GL_ARB_depth_texture GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_occlusion_query GL_ARB_texture_env_dot3 GL_ARB_transpose_matrix GL_EXT_draw_range_elements GL_EXT_multi_draw_arrays GL_NV_depth_clamp GL_NV_fog_distance GL_NV_point_sprite GL_SUN_multi_draw_arrays
VisualID 183, 0xb7
20311 frames in 5.0 seconds = 4062.197 FPS

为什么glxgears在 WSL 中运行如此缓慢?如果它理应能够运行得更快,那么我该如何实现这一点?

更新

根据下面 @allquixotic 的回答,我再次尝试使用该wgl选项运行,方法是选中第二个复选框“Native opengl”。我以前试过这个,但事实证明我需要这样做重启后使其生效。当我glxgears使用此设置运行时,我在控制台上得到了略有不同的读数:

xxxx@DESKTOP-8U2MCOG:~$ glxgears
Running synchronized to the vertical refresh.  The framerate should be
approximately the same as the monitor refresh rate.
23633 frames in 7.5 seconds = 3147.913 FPS
10395 frames in 6.8 seconds = 1529.523 FPS
10395 frames in 6.9 seconds = 1512.829 FPS

现在我很确定我的显示器没有以 1500Hz 的垂直扫描速率运行!所以我认为这可能表明了真正发生了什么;间接渲染系统有些奇怪。我还注意到,当我按 CTRL+C 结束程序时,GL 窗口在我终止程序后继续运行并动画 10-11 秒——如果我只运行了程序 3-4 秒的话。所以我猜想有大量消息排队,或者类似这样的情况......?

答案1

最终实际效果如下:

出于我无法理解的原因,当我违背@allquixotic 的(非常明智的)建议时,我的系统却起作用了。

1. 禁用LIBGL_ALWAYS_INDIRECT

这真的非常困难,因为我必须找到它的设置位置:

  • 文件夹里/etc/profile.d有一个文件wsl-integration.sh
  • 上述文件实际上是一个符号链接;实际文件是/usr/share/wslu/wsl-integration.sh
  • 在该文件中,变量LIBGL_ALWAYS_INDIRECT已设置,因此我注释掉了该行。

2. 做不是使用-wglVcXsrv 的命令行参数(或其 GUI 等效项):

由于我是从 GUI 客户端启动 VcXsrv,这意味着未选中第二个选项框(标题为“Native OpenGL”)。

仅当我完成了这两项更改(并进行了全新的重新启动以确保没有保留 VcXsrv 的旧设置)之后,齿轮glxgears才会以正常速度转动,我可以使用箭头键重新调整它们,就像它们应该工作一样。

答案2

尝试解决你的问题

  1. 在运行需要硬件加速的 Robot OS 程序(如 glxgears)之前,请运行export LIBGL_ALWAYS_INDIRECT=1
  2. 启动 VcXsrv(或 Windows 上的任何 X 服务器)时,将-wgl命令行参数作为命令行参数传递到服务器中。
  3. 如果这不起作用,请尝试使用付费版本的 Xming,而不是 VcXsrv。
  4. 如果这仍然不起作用,那你很可能运气不佳。请阅读下文了解原因。

引擎盖下的解释

在 Windows 的 Linux 子系统 (WSL) 或 Hyper-V 客户机中,硬件加速 OpenGL 只能通过以下方式实现:间接渲染

GLX 是 X11 客户端-服务器协议的协议扩展。X11 客户端-服务器协议是用于客户端和服务器之间通信的网络协议。客户(创建 X 窗口的程序)和服务器(将这些窗口呈现到屏幕上的程序,无论是物理的还是虚拟的)。

桌面Linux 中,GLX 是访问 OpenGL 的标准机制。从客户端程序来看,它基本上是一个两步过程:(1) 与 GLX 对话,然后 (2) 与 OpenGL 对话。第二步取决于您使用的是间接渲染还是直接渲染(即间接 GLX 还是直接 GLX)。

  • 间接渲染:

    • 仅支持最高 OpenGL 版本 1.4(无 GLSL 等)
    • 大多数程序都需要环境变量LIBGL_ALWAYS_INDIRECT=1才能使用它,否则它们默认直接渲染。
    • 使用 GLX 将所有 OpenGL 命令发送到 X 服务器协议
    • X服务器后端使用X服务器本地的OpenGL实现来完成对窗口的渲染。
    • 对网络透明,这意味着它可以通过网络连接和 UNIX 域套接字以及本地工作。
  • 直接渲染:

    • 支持图形驱动程序支持的任何版本的 OpenGL,如果 OpenGL 发布新版本,则最高可达 OpenGL 4.x 或更高版本。
    • LIBGL_ALWAYS_INDIRECT需要环境变量取消设置
    • 使用动态加载将所有 OpenGL 命令发送到可用的符号libGL.so(末尾带有适当的版本,例如 libGL.so.1 等)——这些都是本机函数调用。
    • X 服务器并不直接“看到”OpenGL 渲染命令。它所看到的只是它在帧缓冲区中为图形驱动程序渲染而预留的一个矩形区域。它不知道什么仅被渲染在哪里
    • 不是网络透明的,这意味着它只能在同一台计算机上本地工作。

那里OpenGL 的一个实现,支持 GLX 直接渲染,但——X 服务器不知道——通过网络将 OpenGL 调用传输到硬件加速远程。该产品称为 VirtualGL。但 VirtualGL 没有 Windows 服务器组件,因此无法在 Windows 主机上使用 VirtualGL。如果您在虚拟化中运行 Linux 主机和 Linux 客户机,则可以使用客户机上的 VirtualGL 到主机,以使用主机的显卡在客户机上进行直接渲染。

我不知道“Robot OS”是什么,但如果它只需要 1.4 版或更早版本的 OpenGL 命令,那么使用该-wgl命令在 Windows 主机上运行 X 服务器应该可以正常工作。X 服务器需要支持此标志。我自己从未让它与 VcXsrv 一起工作过,但我知道付费版的 Xming 可以工作。

有几种 X 服务器可以在 Windows 上运行。除了那些非常昂贵的商业实现外,我测试了其中的大多数。在我看来,最适合 OpenGL 的是付费版的 Xming。免费版相当过时,而且不太好。

然而,并不存在——不能存在——Windows X 服务器的实现将在间接渲染模式下(从 WSL 或 Hyper-V 客户端)支持 OpenGL 1.4 以上版本,因为 GLX协议本身没有指定 1.4 以上版本的 OpenGL 调用。

因此,如果 Robot OS 需要 OpenGL 1.4 以上版本,则绝对不可能在 WSL 或 Hyper-V 中运行它并在 Windows X 服务器上获得硬件加速渲染。您必须使用 VMware Workstation 之类的东西。

答案3

遇到了同样的问题并发现 glxgears 很可能只是用绘制请求压倒了 VcXsrv,速度太快以至于它永远无法渲染任何东西。

带有帧速率限制选项的 glxgears 的修改版本的详细信息如下:

https://github.com/tobecodex/glxgears

使用此版本,我可以轻松在 Surface Book 2 上获得 > 800 fps 的齿轮。

我猜测现代显示器缺乏真正的 VSYNC 速率导致 glxgears 尽可能快地向服务器发送垃圾邮件,从而杀死 VcXsrv。

我注意到 MeshLab 和类似程序运行良好,并且 Xming 没有这个问题(但也没有硬件加速)。

所以回答你的问题:不用担心。Gazebo 可能运行得很好。该问题只存在于 glxgears 以及类似年份的应用程序中。

顺便说一句,我发现:export LIBGL_ALWAYS_INDIRECT-wgl的任何组合对我来说都没有什么效果。可能值得再次尝试这些,因为结果几乎肯定会与您在 glxgears 中看到的结果不同。

相关内容