您可以同时创建多少个 OpenGL 渲染上下文是不是有限制?
Posted
技术标签:
【中文标题】您可以同时创建多少个 OpenGL 渲染上下文是不是有限制?【英文标题】:Is there a limit to how many OpenGL rendering contexts you can create simultaneously?您可以同时创建多少个 OpenGL 渲染上下文是否有限制? 【发布时间】:2011-06-24 11:53:15 【问题描述】:我的 .Net Winforms 应用程序在我的主窗口中创建了三个 OpenGL 渲染上下文,然后允许用户弹出其他窗口,其中每个窗口还有两个渲染上下文(使用拆分器)。在第 26 个渲染上下文左右,事情开始变得非常缓慢。新的渲染上下文需要 5 到 10 秒,而不是花费几毫秒来渲染一帧。它仍然有效,只是真的很慢!并且 OpenGL 不会返回任何错误 (glGetError)。
其他窗口工作正常。只是在一定数量后新的渲染上下文会变慢。如果我关闭这些窗口,一切都很好——直到我重新打开足够多的窗口以超过限制。每个渲染上下文都有自己的线程,每个线程都使用一个简单的着色器。当我上传纹理时,似乎发生了减速。但是纹理的大小对我可以创建多少上下文没有影响,OpenGL 窗口的大小也没有。
我在 nVidia 卡上运行,并且在具有不同内存量和不同驱动程序版本的不同 GPU 上看到了这一点。这是怎么回事?应用程序可以创建多少渲染上下文是否有限制?
是否有其他人的应用程序同时具有大量渲染上下文?
【问题讨论】:
另请参阅community.amd.com/thread/184325 以获取有关 AMD 的参考,我感觉 AMD 数量很少(+/-20 ctx?) 【参考方案1】:如果您在将 OpenGL 设置为***多线程方式时遇到了很多麻烦,您也可以从中受益并考虑切换到 Vulkan。请看,按照设计,OpenGL 架构将所有来之不易的上下文/线程分离的绘图操作集中到一个驱动程序线程中,然后将所有这些调用重新分配到映射到每个上下文的虚拟硬件线程上。驱动程序本质上是一个巨大的瓶颈,因为它本身不是线程的,尽管有任何 glewmx 坐在周围。它根本不是为了很好地处理这个问题而设计的。
也就是说,我很好奇您是否使用了旧版本的 Glew,或者您是否以其他方式进行所有扩展处理,因为最新的 glew 库不再支持 mx。又多了一个切换的理由。
【讨论】:
这个问题是10年前问的,哈哈 我确实在发布后就意识到了这一点,但今天我的帖子与刚开始使用 OpenGL 的人非常相关。也许你知道为什么它被否决了,但是如果我今天学习 OpenGL 并遇到这个问题,那么这些知识会很有用。【参考方案2】:正如 Nathan Kidd 所说,限制是特定于实现的,您所能做的就是在通用硬件上运行一些测试。
我在今天的部门会议上很无聊,所以我尝试拼凑一些代码来创建 OpenGL 上下文并尝试进行一些渲染。我尝试使用和不使用纹理进行渲染,使用和不使用前向兼容的 OpenGL 上下文。
事实证明,GeForce 卡的限制相当高(甚至可能没有限制)。对于桌面 Quadro,有 128 个能够正确重绘的上下文的限制,该程序能够再创建 128 个没有错误的上下文,但窗口包含垃圾。
在 ATi Radeon 6950 上更有趣,重绘在窗口 #105 处停止,创建渲染上下文 #200 失败。
如果你想自己尝试,可以在这里找到程序:Max OpenGL Contexts test(有完整的源代码+win32二进制文件)。
结果就是这样。一条建议 - 尽可能避免使用多个上下文。在多个监视器上运行的应用程序可以理解多个上下文,但单个监视器上的应用程序应该求助于单个上下文。上下文切换很慢。这还不是全部。 OpenGL 窗口与另一个窗口重叠的应用程序需要硬件裁剪区域。 GeForce 上有一个硬件剪辑区域,Quadro 上有八个或更多(与游戏相比,CAD 应用程序通常使用与 OpenGL 窗口重叠的窗口和菜单)。如果需要更多区域,则渲染会退回到软件——同样如此——拥有大量 OpenGL 窗口(上下文)并不是一个好主意。
【讨论】:
非常有用的测试程序谢谢你——因为它的价值我在这个 ATI Radeon HD 4870 上顺利更新了 105(如预期的那样)——尽管它在那之后挂了。【参考方案3】:鉴于 OpenGL 驱动程序的多样性,最好的办法可能是检查主要驱动程序(AMD / Intel / NVIDIA / MS Software Render)的行为,并在首次启动时运行测试。例如。如果您可以看到 NVIDIA 总是像您看到的那样变慢,那么只需运行一个快速循环,直到您看到该机器(或者更确切地说,卡)上的限制在哪里。这不是很有趣,但我认为很难可靠地突破极限。
换句话说,“最佳选择”就像之前的回答一样,您无法事先知道。
【讨论】:
【参考方案4】:最好的选择是这个问题没有真正的答案。这可能取决于驱动程序的某些内部限制,甚至是操作系统的硬件。您可能想要检查的是使用 glGet(GL_MAX_TEXTURE_UNITS)
的可用纹理单元的数量,但这可能是指示性的,也可能不是指示性的。
避免这种情况的常见解决方案是在单个上下文中创建多个视口,而不是在单个窗口中创建多个上下文。将共享一个窗口的两个上下文联合到一个具有两个视口和某种 UI 小部件作为拆分器的单个上下文中应该不会太难。多个窗口是另一回事,如果实际需要 26 个单独的 OpenGL 窗口,您可能需要考虑完全重新考虑您的 UI 设计。 我现在很难想到一个真正的 UI 用例实际上需要同时运行 26 个不同的 OpenGL 窗口。也许另一种选择是创建一个包含 5-10 个上下文的池,并仅在用户当前可见的窗口(选项卡?)中重复使用它们。我没有尝试过,但应该可以在一个不包含任何其他内容的普通窗口中创建一个上下文,然后将该窗口从父窗口移动到父窗口,再移动到需要它的任何***窗口。
编辑 - 嗯,其实想一个也不难。支持 WebGL 的最新 Chrome (9.x.x) 可能希望打开许多带有 WebGL 上下文的选项卡……我想知道他们是否以任何方式处理这个问题。刚刚尝试过,在 13 个选项卡后内存不足......这实际上也是一个很好的检查,看看你做错了什么,或者 chrome 和 firefox (4.0.x-beta) 是否有相同的问题
【讨论】:
GL_MAX_TEXTURE_UNITS
肯定与渲染上下文的最大数量无关。以上是关于您可以同时创建多少个 OpenGL 渲染上下文是不是有限制?的主要内容,如果未能解决你的问题,请参考以下文章
我是不是允许在 OpenGL 2.1 的多个共享上下文中同时从同一个缓冲区对象进行渲染?