Shared context and multi-threading

Hi, one thing is still unclear with regard to multiple threads each having own GL context where all share lists / texture memory: is it safe to upload texture data from 2 threads (possibly simultaneously)? Or should just be treated as normal shared resource (between threads) and protected appropriately?

From what I remember you don't need to protect the shared resources. The implementation should do that for you. Nevertheless there are other things you should worry about (at least on GLES 3.0) like:

Changes to the contents of shared objects are not automatically propagated between contexts. If the contents of a shared object T are changed in a context other than the current context, and T is already directly or indirectly attached to the current context, any operations on the current context involving T via those attachments are not guaranteed to use its new contents

Which means that when you are uploading data to texture T on context B you should re-bind T on context A for the changes to take effect. To be more precise you have to rebind after the command is finished on B witch means that you have to do the upload on B then glFinish() and then rebind T in A.

There is a whole section in the spec about that kind of rules (Appendix D on GLES 3.0 spec at least).

is it safe to upload texture data from 2 threads (possibly simultaneously)

What exactly do you mean by that? Are you talking about uploading to two images in the same texture, or one copy overwriting another?

In short, is there an actual race condition on some GPU memory/state?

The specification is pretty nebulous about the effect of data races on shared objects. However, it's pretty clear that multiple readers are fine. So you should assume that it gives a common guarantee:

1: Multiple readers are fine.

2: One writer is fine, so long as nobody else is reading.

Anything else is playing with fire. So yes, I would suggest you use some synchronization.

Also, take into account the special rules that the 4.3 specification defines in section 5 on how to make changes from one context visible in another, as well as how to know when those changes have actually finished. You need to use a sync object to ensure that the change was completed, then bind the object to the context someone to make sure that the completed changes are visible.