2015-09-28 75 views
1

当用OpenGL编程时,应该避免使用glGet函数,因为它们强制GPU和CPU同步,这是否也适用于wgl函数“wglGetCurrentContext”,它获得当前OpenGL上下文的句柄?如果没有,wglGetCurrentContext附近是否还有其他性能问题?做wglGetCurrentContext同步GPU和CPU?

回答

2

根据供应商和驱动程序,所有WGL功能在性能特征的影响方面差别很大。

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

这就是说,设置当前上下文将导致上下文之间的所有方式同步,通常以非常不明确的方式进行。我已经处理了一些AMD和Intel驱动程序错误,其中一些应该通过其他方式同步的东西只能与每帧的冗余MakeCurrent调用同步。

3

有一些误解,在你的问题暗示:

glGet功能应该避免,因为它们迫使GPU和CPU同步

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

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

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

现在,您应该尽可能避免拨打glGet*()电话。主要有两个原因:

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

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

  • 要得到实现的限制,如最大纹理大小等启动时调用一次。
  • 呼叫像glGetUniformLocation()glGetAttribLocation()。确保在着色器链接后您只调用一次。尽管至少在最近的GLSL版本中,通过在着色器代码中使用限定符也可以避免这些问题。
  • glGetError(),仅在调试期间。

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

不过,我不明白为什么调用它是必要的。如果您稍后需要上下文,则可以在创建时将其存储。如果由于某种原因不可能,您可以拨打wglGetCurrentContext()一次,并存储结果。绝对不应该有必要反复调用它。