Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: Can I render and update VBO at the same time?

  1. #1
    Junior Member Newbie
    Join Date
    Jun 2011
    Posts
    3

    Can I render and update VBO at the same time?

    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 :\

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948

    Re: Can I render and update VBO at the same time?

    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.

  3. #3
    Junior Member Newbie
    Join Date
    Jun 2011
    Posts
    3

    Re: Can I render and update VBO at the same time?

    Thanks for your answer. I really appreciate it.

    What I'm trying to do is to benchmark glMapBuffer vs. glMapBufferRange in multi-threaded application. So I hoped it would work (read some part and write to other part at the same time).

    So there is no way to do this? Why should I use glMapBufferRange instead of glMapBuffer? Only advantage is not to map the whole buffer?

  4. #4
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948

    Re: Can I render and update VBO at the same time?

    So there is no way to do this?
    I told you how to do it: "Stop trying to use the buffer after you've mapped it." You use the buffer before you map it.

    What you were doing looks like this:

    Code :
    Thread A: |----[glDraw*]--------|----[glDraw*]--------|
    Thread B: |-[glMap*           ]-|-[glMap*           ]-|

    The [ ] represent the time you spend calling these functions. When mapping, the unmap happens with the ]. The | represents the start of a frame.

    This is not allowed. What you need to do is this:

    Code :
    Thread A: |----[glDraw*]--------|----[glDraw*]--------|
    Thread B: |-------------[glMap* |   ]---------[glMap* |

    You don't even have to map the buffers on thread B. Thread A can map them and pass the pointers to thread B.

  5. #5
    Junior Member Newbie
    Join Date
    Jun 2011
    Posts
    3

    Re: Can I render and update VBO at the same time?

    Thanks. I will try it

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,126

    Re: Can I render and update VBO at the same time?

    Quote Originally Posted by zacharmarz
    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.
    As an aside, this works single-thread beautifully. Yes, you can be updating one part while the GPU is rendering out of another part.

    Can't comment on the multithread though. May need to use some sync objects to ensure that commands stay well-ordered.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •