2

我正在尝试通过带有 X 转发的 SSH 运行 OpenGL+GLUT 程序。该程序提供以下错误,然后是段错误。

Xlib:显示“localhost:10.0”上缺少扩展名“NV-GLX”。

这似乎是因为我的“服务器”计算机有一个 nvidia 卡,然后当客户端没有 nvidia 卡时,它告诉我的客户端计算机使用这些 nvidia 特定的渲染功能。当然,我用谷歌搜索了这个,发现很多其他人也有类似的问题;但是,我真正看到的唯一建议是(https://superuser.com/questions/196838/opengl-program-not-work-with-x-forwarding)尝试

$ export LIBGL_ALWAYS_INDIRECT=1   or use any nonzero value

这没有用。我不关心硬件加速/通过 ssh 连接保持良好的性能。我只想获得窗口渲染。

4

1 回答 1

4

首先,对于 X11,服务器是产生显示输出的计算机。客户端是在远程计算机上运行的程序,利用服务器的显示服务。

您是对的,您收到此消息是因为您的客户端(在远程计算机上运行)是在具有 NVidia GPU 的机器上执行的。然而,造成麻烦的不是 GPU,而是它的驱动程序。Linux OpenGL ABI(应用程序二进制接口)的主要缺点之一是,驱动程序还负责提供系统的libGL.so; 如果你仔细想想,这是一个构思不周的规范,因为它主动阻止为不同供应商的多个 GPU 安装驱动程序。(Windows 从来没有这个问题,因为它是 ICD OpenGL 驱动程序模型)。

无论如何,libGL.so当连接到不运行 NVidia 驱动程序的远程 X 服务器时,您的 NVidia GPU 会看到某些服务器扩展不可用,因此拒绝工作。

那么你能做些什么呢?

好吧,您可以将 Mesa3D 与 NVidia 驱动程序一起安装;大多数 Linux 发行版都有适当的机制(Gentoo eselect,Debian 替代品),可以安装 API 提供程序的多个变体并选择一个作为默认值。

安装 Mesa3D 后,您可以使用LD_PRELOAD环境变量预加载 Mesa3D libGL.so(它将位于某个地方,例如/usr/lib64/opengl/xorg-x11/lib/libGL.so- 使用您的 Linux 发行版的包管理器工具来查找它的位置;或者find /usr -iname 'libGL.so*'选择不包含的目录)nvidia) 而不是系统默认值libGL.so

另一种可行的方法是使用lxc容器,使用 Mesa3D 作为默认 OpenGL 提供程序创建辅助系统安装,当通过 SSH 登录系统时,您将被放入这样的lxc容器中(请注意,如果配置正确,则完全有可能容器只是基础系统上的覆盖层,其中仍然有可能突破到裸系统中)。

Mesa3DlibGL.so将愉快地在远程 X 会话上工作。但是请记住,直到 OpenGL-2.1 才规定了完全间接操作,但没有进一步规定(即对于 OpenGL-3 和以后的许多功能没有定义 GLX 操作码);许多扩展,(也进入OpenGL-3核心)但是定义了GLX操作码,所以如果你依赖于间接OpenGL,你可能会回退到那些。

更新:

在使用扩展和现代 OpenGL 功能时也要小心。所有必须在运行时使用 glXGetProcAddress 加载的函数很容易根本不可用。您收到的段错误表明,您可能正在调用函数指针(通过 GLEW 或类似方式加载),这根本不可用,因此您取消引用导致崩溃的无效指针。始终检查您调用的所有功能和扩展是否实际存在!

于 2014-04-24T10:32:49.827 回答