我刚刚找到以下内容OpenGL 规范ARB_map_buffer_range http://www.opengl.org/registry/specs/ARB/map_buffer_range.txt.
我想知道是否可以使用此扩展进行非阻塞地图调用?
目前,在我的应用程序中,我正在渲染到 FBO,然后将其映射到主机 PBO 缓冲区。
glMapBuffer(target_, GL_READ_ONLY);
然而,这样做的问题是它会在传输数据时阻塞渲染线程。
我可以通过管道化渲染来减少这个问题,但延迟是我的应用程序中的一个大问题。
我的问题是我是否可以将map_buffer_range与MAP_UNSYNCHRONIZED_BIT一起使用并等待地图操作在另一个线程上完成,或者在渲染线程渲染下一帧时推迟同一线程上的地图操作。
e.g.
thread 1:
map();
render_next_frame();
thread 2:
wait_for_map
or
thread 1:
map();
while(!is_map_ready())
do_some_rendering_for_next_frame();
我不确定的是我如何知道映射操作何时准备就绪,规范仅提到“确保正确操作的其他同步技术”。
有任何想法吗?
如果你映射一个缓冲区GL_MAP_UNSYNCHRONIZED_BIT
,驱动程序不会等到 OpenGL 处理完该内存后再为您映射它。所以你或多或少会立即访问它。
问题是这确实not意味着你可以随意读/写该内存。如果 OpenGL 正在读取或写入该缓冲区并且您更改了它...欢迎来到未定义的行为。其中可能包括崩溃。
因此,为了实际使用非同步映射,您必须将您的行为与 OpenGL 对该缓冲区的访问同步。这将涉及使用ARB_sync 对象 http://www.opengl.org/wiki/Sync_Object(如果您仅使用 NVIDIA 并且最近没有更新驱动程序,则为 NV_fence)。
话虽这么说,如果您使用栅栏对象来同步对缓冲区的访问,那么您确实不需要GL_MAP_UNSYNCHRONIZED_BIT
根本不。一旦完成栅栏,或检测到它已完成,您就可以正常映射缓冲区,并且它应该立即完成(除非其他操作也在读/写)。
一般来说,当您需要对缓冲区进行细粒度的写访问时,最好使用非同步访问。在这种情况下,充分利用同步对象将获得您真正需要的东西(能够判断映射操作何时完成)。
附录:以上内容现已过时(取决于您的硬件)。感谢 OpenGL 4.4/ARB_缓冲区_存储 http://www.opengl.org/registry/specs/ARB/buffer_storage.txt,您现在不仅可以不同步映射,还可以保持映射的缓冲区无限期地。是的,您可以映射缓冲区当它在使用时。
这是通过创建不可变存储并为该存储提供(除其他外)GL_MAP_PERSISTENT_BIT
。然后你glMapBufferRange
,也提供相同的位。
现在从技术上来说,这几乎没有改变。您仍然需要将您的操作与 OpenGL 同步。如果您将内容写入缓冲区的某个区域,则需要发出障碍 http://www.opengl.org/wiki/GLAPI/glMemoryBarrier or 显式刷新缓冲区的该区域 http://www.opengl.org/wiki/GLAPI/glFlushMappedBufferRange。如果你正在阅读,你仍然需要使用栅栏同步对象 http://www.opengl.org/wiki/Sync_Object以确保数据确实是there在阅读之前(除非你使用GL_MAP_COHERENT_BIT
同样,您需要在阅读之前发出障碍)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)