【发布时间】:2011-09-02 05:10:09
【问题描述】:
我正在使用 PBO 在我的 cpu 和 gpu 之间异步移动数据。
当从 GPU 移动时,我知道我可以在 PBO 上调用 glMapBuffer 后删除源纹理。
但是,反过来呢?我什么时候知道从 PBO 到纹理 (glTexSubImage2D(..., NULL)) 的传输完成并且我可以安全地释放或重新使用 PBO?是我绑定纹理后还是其他什么?
【问题讨论】:
我正在使用 PBO 在我的 cpu 和 gpu 之间异步移动数据。
当从 GPU 移动时,我知道我可以在 PBO 上调用 glMapBuffer 后删除源纹理。
但是,反过来呢?我什么时候知道从 PBO 到纹理 (glTexSubImage2D(..., NULL)) 的传输完成并且我可以安全地释放或重新使用 PBO?是我绑定纹理后还是其他什么?
【问题讨论】:
我认为在调用glTexImage 之后,您可以安全地删除或重用缓冲区而不会出错,因为驱动程序会为您处理所有事情,包括延迟销毁(这是缓冲区对象的优势)。但这意味着,对glMapBuffer 的调用可能会阻塞,直到前面的glTexImage 副本完成。如果您想重用缓冲区并覆盖其全部内容,通常的做法是在调用glMapBuffer 之前使用glBufferData 重新分配它。这样,驱动程序就知道您不再关心以前的内容,并且可以分配一个您可以立即使用的新缓冲区(包含以前内容的内存然后在不再使用时由驱动程序释放)。请记住,您的缓冲区对象只是一个内存句柄,驱动程序可以随意管理和复制它。
编辑:这意味着以另一种方式(GPU-CPU)您可以在glGetTexImage 返回后删除源纹理,因为驱动程序在后台管理所有内容。是否使用缓冲区对象的决定不应该对调用 GL 函数的顺序和时间产生任何影响。请记住,调用 glDelete... 并不会立即删除对象,它只是将此命令排入 GL 命令流,即使这样,当它真正释放任何内存时,它也取决于驱动程序。
【讨论】:
glReadPixels 从帧缓冲区读取,glGetTexImage 从纹理读取,仅此而已。这只是一个例子,同样适用于glReadPixels。