在 Linux 上与 GLUT 共享上下文

shared context with GLUT on Linux

在我当前的设置中,我有两个由两个 GPU 驱动的显示器。使用 GLUT,我创建了两个 windows(每个显示器一个)并通过在绘图调用中调用 glutSetWindow() 从主线程渲染每个 window.

绘制调用将 Texture2D 渲染为球体(使用 gluSphere()),但 Texture2D 每隔几秒就会换成另一个图像。我已经设置了一个包含 2 个 Texture2D 的数组,因此我可以在显示当前 Texture2D 时加载下一张图像。只要一切都在主线程中运行,这就很好用。

问题是调用 glTexImage2D() 以加载下一张图像会挂起我的绘图调用,因此我需要在不同的线程上调用 glTexImage2D()。在不同的线程上调用 glTexImage2D() 会崩溃,因为 OpenGL 上下文似乎没有共享。 GLUT 似乎没有提供共享上下文的方法,但我应该能够通过 glXGetCurrentContext().

在 Linux 上获取上下文

我的问题是,如果我通过此调用获得上下文,我如何才能将其设为共享上下文?这甚至可以与 GLUT 一起使用吗?另一种选择是切换到不同的库来替换 GLUT,例如 GLFW,但在那种情况下,我将放弃一些方便的函数,例如 gluSphere()。如果无法与 GLUT 共享上下文,有什么建议吗?

使用 GLX 上下文共享是在创建上下文时建立的;与 WGL 不同,您不能事后才建立这种共享。由于 GLUT 没有上下文共享功能(FreeGLUT 可能有,但我不确定)这不会很简单。

I have two displays that are being driven by two GPUs.

除非这些 GPU 是 SLi-ed 或 CrossFire-ed,否则您无法在它们之间建立上下文共享。

The problem is that the call to glTexImage2D(), to load the next image, hangs my draw call, so I need to call glTexImage2D() on a different thread.

如果图片大小相同,使用glTexSubImage2D替换。还可以使用像素缓冲区对象异步加载图像数据,使用甚至不需要 OpenGL 上下文的辅助线程!

概述步骤:

在 OpenGL 上下文线程中:

正在发起传输

  • glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID)
  • void *p = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
  • 信号传输线程
  • 继续正常绘图操作

在转帖中

信号开始传输

  • 将数据复制到映射缓冲区
  • 信号 OpenGL 上下文线程

在 OpenGL 上下文线程中:

收到完成传输的信号

  • glUnmapBuffer
  • glTex[Sub]Image
  • sync = glFenceSync
  • 继续使用纹理
  • 绘图

在绘图循环的进一步迭代中

  • 轮询 syncglClientWaitSync 使用超时 0
  • 如果等待同步 returns 发出信号切换到新纹理并删除旧纹理
  • 否则继续使用旧纹理绘制