I have simple application. It has two threads. Each thread has it’s own rendering context, but they share one VBO (this is working, I tested it).
Now what I want: One thread is rendering some data from first half of VBO and the second thread is updating second part of VBO.
When I don’t update VBO, it’s working fine.
But I have some weird issues when updating. When I use glMapBuffer to update VBO (in second thread), it’s most time rendering nothing (in first thread) - whole screen is clear (after glClear call). It looks like it can’t touch data from VBO (this is understandable, because whole buffer is mapped and so it can be locked somehow).
I tried to use glMapBufferRange, which has flag GL_MAP_UNSYNCHRONIZED_BIT. This should mean: don’t wait and use VBO as you want, I will synchronize it by myself. Also - when I map only range of VBO and render data from other part, it shouldn’t be waiting. But there are the same issues as with glMapBuffer.
Can anybody explain why or help me, how to fix this? This is my first multi-thread OpenGL app :\
OpenGL’s multithreading rules are quite simple. OpenGL is reentrant. That’s all it guarantees.
That is, you can have two separate contexts. You can mess with non-object state in two separate contexts. You can call the same functions in different contexts without problems. However, you cannot modify object state that is shared across contexts unless you ensure that the two sides are not simultaneously reading/modifying it. If you do, undefined behavior ensues.
This should mean: don’t wait and use VBO as you want, I will synchronize it by myself.
No, it means “the mapping will start now, regardless of whether the buffer object is currently being used as source/destination data.” It does not cause the API to bypass the fact that you cannot use a buffer that is currently mapped as a source or destination. While the buffer is mapped, from whichever thread, you cannot initiate an operation that reads from or writes to it. That is part of the object’s state (whether it is mapped or not); mapping it in one thread means that the object is mapped.
Can anybody explain why or help me, how to fix this?
Stop trying to use the buffer after you’ve mapped it. On thread A, do your rendering. After you’re finished rendering for the current frame, have thread B start doing its poking at the data with UNSYNCHRONIZED. Thread A cannot start rendering again until thread B is finished.