I have a large panel with multiple user controls and have two options before I proceed:
1. Take a single context, (maybe define one FBO per control), and render each control data to this context via different threads.
2. Take one context per control and render to it normally with its own thread (multiple contexts, multiple threads).
Since concurrency is very important for me (data load is high) which approach is better suited for me? How should I manage multiple threads accessing the same thread?
You’re right except that all rendering is done in a single window. I’m building something like task-manager’s performance tab in windows: a single windows form (maybe in future, a WPF panel) which contains about 16 analytic histograms (each showing data from its proprietary source of 10^8 points loaded into its VBO). that would be 16 rectangular panes on a form which show data using OpenGL. Since data load in high and each dataset has a different source, I’ll be uploading data to each VBO from a separate thread.
Thanks GClements. I know that about contexts and I’ll be using my own dispatcher to keep track of the current context and who has it current… but since the context switching process is also a time consuming task, the question remains: single context (maybe with multiple FBOs) or multiple contexts? (see my reply to Alfonse)
I wouldn’t recommend that. Unless a dual copy engine is used, I think the fastest way to update resources is to use the drawing thread itself. The resource preparation threads should just feed it through message-queues.
Who said that you should, or even could, access VBO without a context being bound to the thread executing OpenGL commands? I just said you should prepare data for VBOs in separate threads and post them to the rendering thread (with bound context) through message queues. The rendering context should upload data using glBufferSubData() at its disposal.
You don’t access the VBO, you access the memory that it is mapped to, and all threads in a process share their memory. You have to be careful regarding synchronization, but otherwise it is perfectly safe.
So that would be, a single thread uploading the whole data points to their related VBOs. I think my current bottleneck is data transfer to the GPU, not data processing. Currently, I use multiple threads (one context per graph) to transfer data to GPU concurrently. I wonder if your approach is faster?
So I’ll need a dispatcher (or thread manager) which controls which thread is currently accessing a specific VBO. I think that is what MakeCurrent does! But this aside, your suggestion in accessing VBO memory outside the context is quite interesting.
Exactly! The rendering thread (in my opinion) should be the only one that communicate with the driver through OpenGL calls.
Probably, but you cannot transfer data faster than your system supports. If you are not using dual copy engine you cannot transfer data and draw at the same time! And even with the dual copy engine it is impossible to transfer several streams in parallel. So, allocate a time-slot for data uploading and the other time-slot for rendering. They have to be executed in sequence, never in parallel.
As I already mentioned above, you cannot benefit from concurrency in this case. Furthermore, I think you waste a lot of time in synchronization or take a risk to make something wrong if synchronization is not done correctly. Also, switching contexts is expensive. You also noted that in the beginning of this thread. I hoped that you would realized it by yourself. That’s why I interfered lately. Don’t wonder, try it. VBO mapping is useful only for transform feedback (also in my opinion, someone might disagree with me, but we could debate on this). Avoid such “gymnastics” for transferring data to VBO. I hope it is obvious, but if it is not, I could elaborate it.
[QUOTE=Aleksandar;1265659]Exactly! The rendering thread (in my opinion) should be the only one that communicate with the driver through OpenGL calls.
Avoid such “gymnastics” for transferring data to VBO. I hope it is obvious, but if it is not, I could elaborate it.[/QUOTE]
Thanks Aleksandar! this is the exact answer I’ve been looking for… I was always worried if putting aside the parallelism was a right move in regard to GPU and couldn’t get a definite answer for that… and I think it’s because this concept is somehow paradoxical with what we’ve learned about OOP and concurrency.
So that would be for me, rendering all my graphs in a single context (probably with multiple FBOs) and making this exception in my program’s concurrency to transfer data to the GPU via a single thread.