即使我之前交换了缓冲区,在1个像素上使用glReadPixels也会使管道停顿。 我不需要同步,我可以这样做:
pixel=DEFAULT_VALUE;
while (1){
draw(pixel);
swapBuffers();
pixel=glRead???;
}
如何以优化(不停滞)的方式做到这一点?
答案 0 :(得分:4)
您可以通过Pixel Buffer Objects (PBOs)进行异步像素传输。当您在没有PBO的情况下发出读取调用时,将刷新管道并且CPU必须等待GPU完成呈现和传输数据。使用PBO,您可以提前提供缓冲区,并且在GPU准备就绪时将数据复制到该缓冲区中,因此它不会停止。当你尝试在它准备好之前访问那个缓冲区时(例如通过glGetBufferSubData()
或映射该缓冲区进行读取等),它当然会停止。理想情况下,在读回数据之前,您可以在访问缓冲区之前排队其他一些渲染命令,还可以执行其他一些CPU工作。我链接的扩展规范有一个示例部分,非常有趣。
这些东西也可以与sync objects结合使用。在这种情况下,您可以在读取调用之后添加栅栏同步,这将把数据复制到PBO中。然后,在CPU上,您可以实际检查操作是否已完成。如果没有,你可以做一些其他工作并检查。
所有这些异步传输的主要问题是您将吞吐量换成延迟。所以如果你需要立即获得该像素值,并且对于GPU和CPU有任何其他可以在中间完成的工作,那么就没有太大的收获。那么你就无法真正避免拖延。