Using multiple OpenGL contexts? [ReOpened]
-
wrote on 17 Oct 2012, 11:43 last edited by
Hi everyone,
I'm using a machine with 2 nvidia quadro cards. Is it somehow possible to get multiple QT OpenGL contexts to have one for each graphic card in different threads?
Sincerely,
Seraph -
wrote on 17 Oct 2012, 16:26 last edited by
Well, what operating system are you using? In Qt the part of OpenGL that is not platform agnostic is context creation. You have GLX on *nix (including Linux), AGL on the Mac, WGL on Windows...
Determining which graphics card is going to be bound to the context you will use is done at creation.
Depending on your platform you should look for the proper way to do that using one of the above-mentioned APIs. -
wrote on 17 Oct 2012, 18:22 last edited by
With Qt5 create a QOpenGLContext and call QopenGLContext::setScreen( QScreen* screen ) on it before you call QOpenGLContext::create(). This should ensure that the context is created using the implementation responsible for that screen.
-
wrote on 18 Oct 2012, 08:37 last edited by
I'm using Ubuntu 12.04 LTS.
The thing is that these APIs can only provide that only one Context is active at the same time, which means, that one graphic card has to wait for the other card to be done rendering.
The nVidia Quadro cards are able to do that parallel. That means 2 OpenGL contenxts running in two different threads on each graphic card. So the frames can be drawn synchronous. I guess I won't find a way to do that with QT OpenGL widgets. -
wrote on 18 Oct 2012, 08:48 last edited by
Could you file a bug report about this at http://bugreports.qt-project.org please? Sounds like the current context is probably stored in per-thread storage and needs to be extended to handle the case of high-end cards that can do this.
If only I had a couple of £k to spend on getting some... ;)
-
wrote on 19 Oct 2012, 09:35 last edited by
OpenGL is not thread safe. What you are trying to do is feasible, you only have to call the makeCurrent on each created context in its own thread: Thread1 can deal with GPU1 and Thread2 with GPU2.
-
wrote on 19 Oct 2012, 11:23 last edited by
OK... Sounds good, but has QT any implemented classes/functions to use make current? Or do I have to use the APIs you mentioned lately?
If I have to use a API for example GLX, is there a way to get the contexts/windows from QT or won't that be necessary anymore?Thanks for your answers.
-
wrote on 19 Oct 2012, 11:32 last edited by
You can use the class QGLContext and call makeCurrent() on that.
As explained in ZapB's post, if you call setScreen on the context object before actually creating the context (by passing the object to a QGLWidget constructor), you can achieve what you want. -
wrote on 19 Oct 2012, 11:34 last edited by
In Qt5 similar is achieved using QOpenGLContext instead of QGLContext which also avoids the QtWidgets dependency.
-
wrote on 7 Oct 2013, 11:50 last edited by
Hi there,
I know this thread was closed, already, but i have a problem with the solution.
I am creating the QOpenGLContext objects with the appropriate screens.
(0 and 1 for graphics card 1 and 2)
I have two threads each creating one context (i only use openGL commands within the rendering threads!).
Before i render a frame with one of these threads i call the makeCurrent() method of the appropriate QOpenGLContext instance.That works fine so far... but my graphics card monitor (GPU-Z) does not show any activity on my second graphics card (but almost 100% gpu load on my first card) nor can i recognize any speed up while rendering.
Is that a bug? Did anyone try this with nVidia? Do i have to create my context with AGL, WGL like rcari said?Thanks in advance
-
wrote on 6 Dec 2013, 08:18 last edited by
ZapB and rcari are wrong, there is no implementation for windows. To choose a graphics card on Windows OS's you need to create the window on the right screen for AMD cards. But Qt uses a window dummy to create the context with no position setting so i guess this won't work, because the DC is always created from the primary graphics card then. To do this on NVidia you need the WGL_NV_gpu_affinity extension to choose the DC. But Qt doesn't load these functions for this extension. I did the hack by modifying the qwindowsglcontext.h and qwindowsglcontext.cpp and load these functions in QOpenGLStaticContext class. Then I modified the Constructor of QWindowsGLContext and created the DC with the NVidia extension and this works. So there is need to improve this for the next version where you can explicitly choose the GPU you want to use for the context, how about 6.0 or 7.0? :D
-
wrote on 6 Dec 2013, 10:31 last edited by
Patches welcome. ;) Please submit it to gerrit.