Buffer orphaning and multiple context

Hi,

I would like to ask if anybody knows whether buffer orphaning works across thread boundary.
More specifically, I’m interested whether the following would work:

  • Thread #1 orphans the buffer and uploads new data using BufferData
  • Thread #2 uses the buffer for drawing after thread #1 called BufferData

When you say ‘orphans’, you mean BufferData(…, null) or something else entirely?

Actually orphaning happens no matter if you pass NULL as pointer or if you pass in an actual client side buffer to fill the buffer with.
I mean orphaning by using BufferData. I don’t think that the last argument matters.

Correct me if I’m wrong but only one thread can access the OpenGL context at a time (at least with WGL) so, as long as you make sure BufferData returned before using the data in another thread, yes it should work because there’s just one command queue.

The two threads, of course, use their own rendering context. I thought it is obvious. Actually if I would render to the same context from two threads then it wouldn’t work. I think it is not even supported anyway.

http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html#one

From the spec of ARB_vertex_buffer_object:

"Buffer objects may be shared by rendering contexts, as long as the server
portion of the contexts share the same address space.  (Like display lists
and texture objects, buffer objects are part of the server context state.)
OpenGL makes no attempt to synchronize access to buffer objects.  If a
buffer object is bound to more than one context, then it is up to the
programmer to ensure that the contents of the object are not being changed
via one context while another context is using the buffer object for
rendering.  The results of changing a buffer object while another context
is using it are undefined."

What is unclear to me is whether context #1 might still be writting to PBO once BufferData returned, so you might have to issue a glFinish in thread #1 before using the buffer in thread #2.
My guess would be that it is not necessary.

After some seach, it seems you should be using some fences for synchronization (better than glFinish): http://www.opengl.org/wiki/Sync_Object

Okay, to be more precise:

I know that in order to ensure the correctness of the data I most probably have to use sync objects but I’m more concerned about that orphaning the buffer object will involve the allocation of a new memory range and this information is encapsulated in the client side data of the buffer object. I’m more concerned about whether thread #2 will be aware of the changed client side data of the buffer object which is actually up to the driver implementation as this is a CPU sync issue rather than a GPU one.

Should the actual memory range be reallocated by a call to BufferData, the buffer OBJECT itself remains, so there is no orphaning here: the buffer handles in both threads will still refer to the same valid OpenGL object.

As long as you’re referencing buffer data with origin-relative adresses (no “bindless” rendering) and you’re not mapping buffer data to client process memory, this should be OK. It’s likely you don’t even have to unbind buffer from context #1 before using it in context #2 as long as you properly ensure there’s no concurrent accesses to the underying data.

Buffer objects are server state. Only binding points and mappings are client-side.

Buffer objects are server state.

On a logical level, yes, it is specified to be so. Maybe I was incorrectly used the “client-side” expression in this case. However, CPU side data in the driver is the one that holds the information about where the storage of the buffer object is, so there is need for some CPU side sync. But suppose that’s done in the driver anyway (at least it is done as a result of a bind).

Anyway, I’ll try it out and I’ll see…