PDA

View Full Version : Buffer orphaning and multiple context



aqnuep
01-11-2011, 11:16 AM
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

Stephen A
01-11-2011, 01:05 PM
When you say 'orphans', you mean BufferData(..., null) or something else entirely?

aqnuep
01-11-2011, 01:14 PM
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.

shadocko
01-12-2011, 10:21 AM
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.

aqnuep
01-12-2011, 04:30 PM
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.

Dark Photon
01-12-2011, 06:39 PM
http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html#one

shadocko
01-13-2011, 02:05 AM
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.

shadocko
01-13-2011, 02:38 AM
After some seach, it seems you should be using some fences for synchronization (better than glFinish): http://www.opengl.org/wiki/Sync_Object

aqnuep
01-13-2011, 03:36 AM
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.

shadocko
01-13-2011, 07:04 AM
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.

aqnuep
01-13-2011, 10:13 AM
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...