wglGetCurrentContext是否同步GPU和CPU?

时间:2015-09-28 21:49:43

标签: performance opengl wgl

使用OpenGL进行编程时,应避免使用glGet函数,因为它们会强制GPU和CPU同步,这是否也适用于wgl函数" wglGetCurrentContext"获取当前OpenGL上下文的句柄?如果没有,围绕wglGetCurrentContext还有其他任何性能问题吗?

2 个答案:

答案 0 :(得分:4)

你的问题暗示了一些误解:

  

应该避免使用glGet函数,因为它们会强制GPU和CPU同步

第一部分是真的。第二部分不是。大多数glGet*()调用不强制GPU / CPU同步。它们只获得存储在驱动程序代码中的状态,并且根本不涉及GPU。

有一些例外,其中包括实际获取GPU生成数据的glGet*()调用。典型的例子包括:

  • glGetBufferSubData():必须阻止GPU生成数据(例如使用转换反馈)。
  • glGetTexImage():阻止GPU生成纹理数据(例如,如果用作渲染目标)。
  • glGetQueryObjectiv(..., GL_QUERY_RESULT, ...):如果查询尚未完成,则阻止。

现在,您应尽可能避免glGet*()次呼叫。主要有两个原因:

  • 大多数都是不必要的,因为它们会查询您自己设置的状态,因此您应该已经知道它是什么。任何不必要的电话都是浪费。
  • 在多线程驱动程序实现中,它们可能会导致线程之间的同步。因此,它们可能会导致同步,但不会导致GPU。

glGet*()来电当然有一些很好的用途,例如:

  • 获取实施限制,例如最大纹理大小等。在启动期间调用一次。
  • 调用glGetUniformLocation()glGetAttribLocation()。确保在着色器链接后只调用一次。即使在着色器代码中至少在最近的GLSL版本中使用限定符也可以避免这些。
  • glGetError(),仅在调试期间。

关于wglGetCurrentContext(),我怀疑它会非常昂贵。当前上下文通常存储在某种线程本地存储中,可以非常有效地访问它。

尽管如此,我还是不明白为什么要这么做。如果稍后需要再次使用上下文,则可以在创建时将其存储起来。如果出于某种原因无法做到这一点,您可以拨打wglGetCurrentContext()一次,然后存储结果。绝对不需要反复调用它。

答案 1 :(得分:2)

根据供应商和驱动程序的不同,所有WGL功能对性能特征的影响差异很大。

我不认为wglGetCurrentContext会是一个特别高性能的占用呼叫(除非你做了很多次)。由于WGL函数通常与GL上下文的状态向量分离。

话虽如此,设置当前上下文将导致上下文之间的所有方式同步,通常是以非常无记录的方式。我已经处理了几个AMD和Intel驱动程序错误,其中一些应该通过其他方式同步的东西只能与每帧的冗余MakeCurrent调用同步。