在 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
- 继续使用旧纹理
绘图
在绘图循环的进一步迭代中
- 轮询
sync
与 glClientWaitSync
使用超时 0
- 如果等待同步 returns 发出信号切换到新纹理并删除旧纹理
- 否则继续使用旧纹理绘制
在我当前的设置中,我有两个由两个 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
- 继续使用旧纹理 绘图
在绘图循环的进一步迭代中
- 轮询
sync
与glClientWaitSync
使用超时 0 - 如果等待同步 returns 发出信号切换到新纹理并删除旧纹理
- 否则继续使用旧纹理绘制