使用ubuntu在不同显示器上共享opengl上下文
我们有一个使用 3 个显卡在不同屏幕上有多个窗口的应用程序。每个窗口都使用 opengl 来渲染字体、图像等... 到目前为止,除了共享资源之外,这种方法效果很好。我们尝试实现这样的东西(fenster是一个自定义类,用于存储上下文等信息...):
//a list of display names
vector<string> displays;
displays.push_back(":0.0");
displays.push_back(":0.1");
displays.push_back(":0.2");
displays.push_back(":0.3");
displays.push_back(":0.4");
//and then we loop them
FOREACH(string dispName in displays): //dummy code
static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
Display* disp;
if(dispName != "default")
disp = XOpenDisplay(dispName.c_str());
else
disp = XOpenDisplay(NULL);
if(disp == NULL)
{
cout << "ERROR GETING DISPLAY " << dispName << endl;
return NULL;
}
cout << "CREATING WINDOW ON SCREEN "<< dispName << endl;
XVisualInfo *vi = glXChooseVisual(disp, DefaultScreen(disp), dblBuf);
fenster->display = disp;
fenster->window = XCreateSimpleWindow(disp, RootWindow(disp, vi->screen), 1, 1, 500, 500, 0, BlackPixel (disp, 0), BlackPixel(disp, 0));
XSetStandardProperties(fenster->display, fenster->window, "main", "main", None,NULL, 0, NULL);
XMapWindow(disp, fenster->window);
if(fensterList.size()==0)
fenster->glXContext = glXCreateContext(disp, vi, NULL, GL_TRUE);
else
fenster->glXContext = glXCreateContext(fensterList[0]->display, vi, fensterList[0]->glXContext, GL_TRUE);
XSelectInput(disp, fenster->window, ButtonPressMask|KeyPressMask);
glXMakeCurrent(disp, fenster->window, fenster->glXContext);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 0.0);
XFlush(disp);
fenster->id = fensterList.size();
fensterList.push_back(fenster);
fenster->setup();
这编译得很好,但在运行时产生以下错误:
CREATING WINDOW ON SCREEN :0.0
CREATING WINDOW ON SCREEN :0.1
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 137 (GLX)
Minor opcode of failed request: 3 (X_GLXCreateContext)
Serial number of failed request: 90
Current serial number in output stream: 91
当我尝试在同一个窗口上创建多个窗口时,代码有效桌面(使用显示:0.0)。
系统是ubuntu 10.10,使用专有的ATI驱动。
有什么想法吗?有可能吗?
We have an application with multiple windows on different screens using 3 graphic cards. Each window uses opengl to render fonts, images etc...
This works very well so far, except for sharing resources. we tried to implement something like this (fenster is a custom class to store information like context, etc...):
//a list of display names
vector<string> displays;
displays.push_back(":0.0");
displays.push_back(":0.1");
displays.push_back(":0.2");
displays.push_back(":0.3");
displays.push_back(":0.4");
//and then we loop them
FOREACH(string dispName in displays): //dummy code
static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
Display* disp;
if(dispName != "default")
disp = XOpenDisplay(dispName.c_str());
else
disp = XOpenDisplay(NULL);
if(disp == NULL)
{
cout << "ERROR GETING DISPLAY " << dispName << endl;
return NULL;
}
cout << "CREATING WINDOW ON SCREEN "<< dispName << endl;
XVisualInfo *vi = glXChooseVisual(disp, DefaultScreen(disp), dblBuf);
fenster->display = disp;
fenster->window = XCreateSimpleWindow(disp, RootWindow(disp, vi->screen), 1, 1, 500, 500, 0, BlackPixel (disp, 0), BlackPixel(disp, 0));
XSetStandardProperties(fenster->display, fenster->window, "main", "main", None,NULL, 0, NULL);
XMapWindow(disp, fenster->window);
if(fensterList.size()==0)
fenster->glXContext = glXCreateContext(disp, vi, NULL, GL_TRUE);
else
fenster->glXContext = glXCreateContext(fensterList[0]->display, vi, fensterList[0]->glXContext, GL_TRUE);
XSelectInput(disp, fenster->window, ButtonPressMask|KeyPressMask);
glXMakeCurrent(disp, fenster->window, fenster->glXContext);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 0.0);
XFlush(disp);
fenster->id = fensterList.size();
fensterList.push_back(fenster);
fenster->setup();
This compiles fine, but produces the following error on runtime:
CREATING WINDOW ON SCREEN :0.0
CREATING WINDOW ON SCREEN :0.1
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 137 (GLX)
Minor opcode of failed request: 3 (X_GLXCreateContext)
Serial number of failed request: 90
Current serial number in output stream: 91
The code works when I try to create multiple windows on the same desktop (using display :0.0).
The system is ubuntu 10.10, using the proprietary ATI driver.
Any ideas? Is it even possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
来自 http://www.opengl.org/sdk/docs/man/ xhtml/glXCreateContext.xml:
规范措辞表明,如果您有直接渲染上下文并且它们都是由同一进程创建的,那么这应该可行,但实际上 X 服务器和/或 libGL 可能会有不同的想法。
From http://www.opengl.org/sdk/docs/man/xhtml/glXCreateContext.xml :
The spec wording suggests this should work if you have direct rendering contexts and they're all created by the same process, but in practice the X server and/or libGL might think differently.
每个显卡都有自己的状态、自己的纹理内存等。也许如果你在交火模式下运行,它们可以直接访问彼此的内存,但你还没有提到这一点。
正如 Nathan 在规范中发现的那样,共享资源需要一个公共地址空间。但我认为这是在谈论 GDRAM 地址空间,而不是单个进程。
Each graphic card has its own state, its own texture memory, etc. Maybe if you're running in Crossfire mode they could access each others' memory directly, but you haven't said anything about that.
Sharing resources requires a common address space as Nathan found in the spec. But I think this is talking about GDRAM address space, not a single process.