在特定显示器上打开 GL 的 X11 窗口

Opening an X11 window for GL on a specific display

本文关键字:GL X11 窗口 显示器      更新时间:2023-10-16

我正在接管一些遗留代码,它正在使用Xlib + glX来创建其绘图窗口。但是,当显示名称设置为:0.0以外的任何值时,窗口创建将失败。

我能够在一个最小的示例中重现此行为:

#include <X11/Xlib.h>
#include <GL/glew.h>
#include <GL/glx.h>
int main()
{
    Display* display = XOpenDisplay(":0.1");
    GLint vi_att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
    XVisualInfo* vi = glXChooseVisual(display, 0, vi_att);
    Window root = DefaultRootWindow(display);
    Colormap cmap = XCreateColormap(display, root, vi->visual, AllocNone);
    XSetWindowAttributes swa;
    swa.colormap = cmap;
    swa.event_mask = ExposureMask;
    Window window = XCreateWindow(display, root, 0, 0, 200, 400, 0,
        vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask,
        &swa);
    GLXContext context = glXCreateContext(display, vi, NULL, GL_TRUE);
    glXMakeCurrent(display, window, context);
    XMapWindow(display, window);
    XFlush(display);
    return 0;
}

执行此示例时,我收到控制台消息

X Error of failed request:  BadMatch (invalid parameter attributes)
    Major opcode of failed request:  78 (X_CreateColormap)
    Serial number of failed request:  21
    Current serial number in output stream:  23

以及逐步执行各种例程,我发现我确实得到了有效的显示,并且我确实得到了有效的视觉效果问题出现在glXCreateContext.

为了清楚起见,:0.1是一个有效的显示器(我已经为我的显示器设置了单独的 X 显示器来测试这一点),有趣的是,它与我正在执行代码的显示器没有区别。起初,我认为在不同的显示器上设置窗口是行不通的,但是使用显示器:0.0运行示例:0.1可以正常工作。从:0.1运行:0.1不会。

更有趣的是,选择 NULL 作为参数XOpenDisplay并在:0.1显示屏上运行它也会产生相同的错误。

有多个屏幕表示您的 X 服务器已设置为Zaphod模式。根据您使用的驱动程序以及图形输出的配置方式,OpenGL 可能根本不起作用或仅在其中一个屏幕上工作。

请发布您的/var/log/Xorg.0.log,以便我为您提供更多详细信息。

但是我已经可以告诉你,Zaphod模式和OpenGL在大多数驱动程序和系统配置中都很难。

因评论而更新

好的,鉴于您的Xorg.0.log,您只能在其中一个屏幕上创建OpenGL上下文也就不足为奇了:您只有一个GPU,如行所示(请注意相同的PCI Bus-ID):

[    18.192] (II) NVIDIA(0): NVIDIA GPU GeForce GTS 450 (GF116) at PCI:1:0:0 (GPU-0)
…
[    18.214] (II) NVIDIA(1): NVIDIA GPU GeForce GTS 450 (GF116) at PCI:1:0:0 (GPU-0)

并在具有不同输出的多个 X 屏幕上使用它。驱动程序根本不支持它,并且已经有很好的文档记录

(...) 窗口不能在 X 屏幕之间拖动,硬件加速的 OpenGL 不能跨越 (...)X 屏幕 (...)

然而,实际的问题是:为什么为了鲍勃,你首先使用多屏幕(=Zaphod)模式?只有一种情况是明智的。也就是说,如果您有多个显卡,您无法在一台机器中互连(SLi或CrossFire或不同型号或供应商),并且您希望在单个X显示器多屏幕配置中一起使用它们。

除此之外,您应该使用TwinView,因为它可以满足您对它的期望。


请注意,如果您希望通过将多个显卡插入一个盒子来获得更多的屏幕空间,您可以使用DMX(分布式多头X)和Xpra或Chromium的组合,但这需要一些认真的修补和AFAIK没有人记录Xpra方法到这个数据(虽然可能是一个很好的周末项目)。