Opengl非同步/非阻塞映射 [英] Opengl Unsynchronized/Non-blocking Map

查看:235
本文介绍了Opengl非同步/非阻塞映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚找到以下 ARB_map_buffer_range 的OpenGL规范.

I just found the following OpenGL specification for ARB_map_buffer_range.

我想知道是否可以使用此扩展程序进行非阻塞地图调用?

I'm wondering if it is possible to do non-blocking map calls using this extension?

当前在我的应用程序中,我正在渲染到FBO,然后我将其映射到主机PBO缓冲区.

Currently in my application im rendering to an FBO which I then map to a host PBO buffer.

glMapBuffer(target_, GL_READ_ONLY);  

但是,这样做的问题是它在传输数据时阻塞了渲染线程.

However, the problem with this is that it blocks the rendering thread while transferring the data.

我可以通过流水线化渲染来减少此问题,但是延迟是我应用程序中的大问题.

I could reduce this issue by pipelining the rendering, but latency is a big issue in my application.

我的问题是我是否可以将map_buffer_range与MAP_UNSYNCHRONIZED_BIT一起使用,并等待map操作在另一个线程上完成,还是在渲染线程渲染下一帧时将map操作推迟到同一线程上.

My question is whether i can use map_buffer_range with MAP_UNSYNCHRONIZED_BIT and wait for the map operation to finish on another thread, or defer the map operation on the same thread, while the rendering thread renders the next frame.

例如

thread 1:

map();
render_next_frame();

thread 2:

wait_for_map

thread 1:

map();
while(!is_map_ready())
   do_some_rendering_for_next_frame();

我不确定的是我如何知道映射操作何时准备就绪,该规范仅提及其他同步技术以确保正确的操作".

What I'm unsure of is how I know when the map operation is ready, the specification only mentions "other synchronization techniques to ensure correct operation".

有什么想法吗?

推荐答案

通常,无法执行非阻塞地图",但可以进行无阻塞地图.

In general, it is not possible to do a "nonblocking map", but you can map without blocking.

之所以没有非阻塞映射",是因为函数调用返回的那一刻起,您就可以访问数据,因此驱动程序必须肯定地确保它在那里.如果尚未传输数据,则驱动程序只能执行其他操作.
线程并没有使它变得更好,甚至可能变得更糟(添加了同步和上下文共享问题).线程无法神奇地消除传输数据的需要.

The reason why there can be no "nonblocking map" is that the moment the function call returns, you could access the data, so the driver must make sure it is there, positively. If the data has not been transferred, what else can the driver do but block.
Threads don't make this any better, and possibly make it worse (adding synchronisation and context sharing issues). Threads cannot magically remove the need to transfer data.

这将导致如何不阻止映射:仅在确定传输完成后才进行映射.一种安全的方法是在翻转缓冲区之后或在glFinish之后或在等待查询/栅栏对象之后映射缓冲区.如果您迫不及待要交换缓冲区,则最好使用围栏.栅栏不会使管道停顿,但会告诉您是否已完成传输(glFinish可能会或可能不会,但会可能停顿). 交换缓冲区后的读取也是100%安全的,但是如果您需要同一帧内的数据,则可能无法接受(尽管如此,它非常适用于屏幕截图或用于计算色调映射的直方图).

And this leads to how to not block on mapping: Only map when you are sure that the transfer is finished. One safe way to do this is to map the buffer after flipping buffers or after glFinish or after waiting on a query/fence object. Using a fence is the preferrable way if you can't wait until buffers have been swapped. A fence won't stall the pipeline, but will tell you whether or not your transfer is done (glFinish may or may not, but will probably stall). Reading after swapping buffers is also 100% safe, but may not be acceptable if you need the data within the same frame (works perfectly for screenshots or for calculating a histogram for tonemapping, though).

一种不太安全的方法是插入其他内容",并希望在此同时转移完成.

A less safe way is to insert "some other stuff" and hope that in the mean time the transfer has completed.


关于以下评论:
此答案不是不正确.在获得数据之后,除了访问数据,别无所求(这是显而易见的).这意味着您必须以一种方式或另一种方式同步/阻止,别无选择.
尽管从非常古怪的角度来看,您当然可以使用GL_MAP_UNSYNCHRONIZED_BIT来进行无阻塞的地图操作,但这是完全无关的,因为除非您明确地再现<如上所述,em> implicit 同步.无法安全访问的映射毫无用处.


In respect of below comment:
This answer is not incorrect. It isn't possible to do any better than access data after it's available (this should be obvious). Which means that you must sync/block, one way or the other, there is no choice.
Although, from a very pedantic point of view, you can of course use GL_MAP_UNSYNCHRONIZED_BIT to get a non-blocking map operation, this is entirely irrelevant, as it does not work unless you explicitly reproduce the implicit sync as described above. A mapping that you can't safely access is good for nothing.

映射和访问OpenGL将数据传输到的缓冲区而没有同步/阻塞(隐式或显式)意味着未定义的行为",这对于可能是垃圾结果,可能是崩溃"只是更好的表述.
另一方面,如果您明确地进行了同步(例如,使用如上所述的防护),则是否使用未同步标志都无关紧要,因为无论如何都不需要进行任何隐式同步.

Mapping and accessing a buffer that OpenGL is transferring data to without synchronizing/blocking (implicitly or explicitly) means "undefined behavior", which is only a nicer wording for "probably garbage results, maybe crash".
If, on the other hand, you explicitly synchronize (say, with a fence as described above), then it's irrelevant whether or not you use the unsynchronized flag, since no more implicit sync needs to happen anyway.

这篇关于Opengl非同步/非阻塞映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆