opengl驱动程序似乎从glUnmapBuffer变得非常慢?这不可能是对的

时间:2015-08-11 12:07:59

标签: opengl

通过visual studio profiling,我发现我的程序执行时间的近50%都花在了KernalBase.dll上。它在那做什么?我不知道,但主要的是调用它是nvoglv64.dll。据我了解,nvoglv64.dll是opengl驱动程序。而调用nvoglv64.dll的主要功能之一就是我的功能之一。这就是功能。

draw() {
    if (mapped)
    {
        mapped = false;
        glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);
        glUnmapBuffer(GL_ARRAY_BUFFER);
    }
    glBindVertexArray(trianglesVAO); 
    program.bind();
    glDrawElements(GL_TRIANGLES, ...); 
}

我使用此函数的方式如下:我将gl缓冲区异步映射到客户端内存,并用大量三角形填充它。然后我使用上面的函数绘制缓冲区。除此之外,我使用两个缓冲区,每个帧交换一个正在绘制的帧,以及正在写入哪一个。

假设所有人都是异步的。即使glunmap和gldrawelements被认为是异步的,它们应该被放入命令队列中。什么导致减速?

1 个答案:

答案 0 :(得分:2)

  

通过visual studio profiling,我发现我的程序执行时间的近50%都花在了KernalBase.dll上。它在那里做了什么?

按预期映射,取消映射和检查内存状态。

如果您希望所有内容真正异步,并且冒着破坏尚未呈现的数据的风​​险,您可以映射未​​同步的缓冲区(请参阅glMapBufferRange (...))。

否则,会有一些内部驱动程序同步,以防止您修改尚未绘制的内存,这就是您在此处看到的内容。除非有足够的缓冲区来容纳每个挂起的帧,否则不能保持异步。

现在,这里的内容就是你刚才所描述的(2个缓冲区)是不够的。您需要多级缓冲区来防止流水线停顿 - 驱动程序(通常)允许排队超过1帧的命令,并且不允许CPU更改任何挂起帧所使用的内存(当您启动时驱动程序将阻塞尝试呼叫glMapBuffer (...))直到所述帧结束。

3缓冲是一个很好的妥协;如果CPU> s>你可能仍会偶尔产生同步开销。 GPU前面2帧。这种情况(> 2个预渲染帧)表示您受GPU限制,1帧的CPU /驱动程序同步实际上不会改变它。所以你可以阻止渲染线程。