作者:跳花妹535 | 来源:互联网 | 2023-10-12 13:08
Ihavevertexbuffersholdingmeshesofterrainchunks.Whenevertheplayereditsterrain,themesh
I have vertex buffers holding meshes of terrain chunks. Whenever the player edits terrain, the mesh of the corresponding chunk must be regenerated and uploaded to the vertex buffer. Since regenerating the mesh takes some time, I do it in an asynchronous worker thread.
我有一个顶点缓冲,控制着地形块的网格。当玩家编辑地形时,相应块的网格必须重新生成并上载到顶点缓冲区。由于重新生成网格需要一些时间,所以我在异步工作线程中执行。
The issue is that the main threads draws the buffer in the same moment the worker thread uploads new data. That means, after the player editing the terrain, a corrupted chunk gets rendered for one frame. It just flares up once and after that, the correct buffers gets drawn.
问题是,主线程在工作线程上传新数据的同一时刻,绘制缓冲区。也就是说,在玩家编辑地形之后,一个被损坏的块被渲染成一个帧。它只会闪烁一次,然后,正确的缓冲区就会被绘制出来。
This kind of made sense to me, we shouldn't write and read the same data at the same time of course. So instead of updating the old buffer, I created a new one, filled it and swapped them. The swapping was just changing the buffer id stored within the terrain chunk struct, so that should be atomic. Hoever, that didn't help.
这对我来说是有意义的,我们不应该同时写和读同样的数据。因此,我没有更新旧的缓冲区,而是创建了一个新的缓冲区,填充并交换了它们。交换只是改变了存储在地形块结构中的缓冲id,所以应该是原子的。Hoever,没有帮助。
Due to the fact that OpenGL commands are sent to a queue on GPU, they don't have to be executed when the application on the CPU continues. So I may have swapped the buffers before the new one was actually ready.
由于OpenGL命令被发送到GPU上的一个队列,所以在CPU上的应用程序继续执行时,不需要执行它们。所以我可能在新的缓冲区已经准备好之前交换了缓冲区。
I also tried an alternative to switching the buffers, using a mutex for buffer access. The main thread locks the mutex while drawing and the worker thread locks it while uploading new buffer data. However, this didn't help either and it may be because of OpenGL's asynchronous nature, too. The main thread didn't actually draw, but just send draw commands to the GPU. On the other hand, when there really is only one command queue, uploading buffers and drawing them could never occur at the same time, does it?
我还尝试了另一种方法来切换缓冲区,使用互斥锁来进行缓冲区访问。主线程在绘图时锁定互斥对象,工作线程在上传新的缓冲区数据时锁定它。然而,这也没有帮助,这可能是因为OpenGL的异步性质。主线程并没有实际绘制,只是向GPU发送绘制命令。另一方面,当真的只有一个命令队列时,上传缓冲区和绘制它们可能不会同时发生,对吗?
How can I synchronize the vertex buffer access from my two threads to prevent that an undefined buffer gets drawn for one frame?
如何使两个线程的顶点缓冲区访问同步,以防止为一个框架绘制未定义的缓冲区?
1 个解决方案