Question
I have an OpenGL application that will run in machines with diverse multi-GPU configurations (and possibly different Windows versions, from XP to 7). Is there a general way to select the specific GPU that will act as the OpenGL renderer independently of the GPU combination (e.g. NVIDIA + NVIDIA, NVIDIA + AMD, NVIDIA + Intel, etc.)? It has to be a solution that can be applied from application code, i.e. directly in C++ or a script that would be called from the application, with no end-user intervention.
Below are the details of several tests I have done to try to find a solution, starting with very specific cases, but maybe there is a solution that can work in all or most cases.
Is ther any reliable method to force which GPU does the OpenGL rendering?
Any hint will be very appreciated. Thanks in advance!
Tried possible solutions
Windows XP 64 with two NVIDIA Quadro
Testing with combinations of two Quadro cards
- Quadro FX 1700 + Quadro FX 570
- Quadro FX 1700 + Quadro FX 540
- Quadro FX 1700 + Quadro NVS 285
using the same driver (version 275.36) under Windows XP 64-bit, I have had relative success with various methods, such as:
Letting the driver decide.
This solution is only good as long as both cards use the same driver and it decides to use the desired card. So it is too specific and maybe unpredictable.Changing driver settings in code with NVAPI before letting the driver decide.
With this solution it is in theory possible to make the driver decide as I want, but it is hard, needs that both cards use the same drivers and doesn't always work (with FX 1700 + NVS 285 it doesn't work).Changing the main screen.
This has the effect that the application opens in the selected main screen by default. This solution has worked on its own only with the FX 1700 + FX 570 combination. With FX 1700 + FX 540 the renderer depends on the driver settings, independently of the main screen, and with FX 1700 + NVS 285 the renderer is always the FX 1700.Creating the OpenGL context when the window is in a specific screen.
The window can be created in the desired screen, independently of which is the main, but it has the same problems as the above solution.Creating the OpenGL context having enabled only the screen in the desired graphics card and then enabling the other/s.
This is the only way I have found to use the NVS 285 as the renderer, but it is ugly and I don't know if it is automatizable or if it would work in all cases.Trying to select the rendering GPU using the WGL_NV_gpu_affinity extension.
With the combination of the FX 1700 and the FX 570 the extension reports both GPUs as compatible and I can limit the rendering only to one of them. With the FX 1700 + FX 540 pair the extension reports only one compatible GPU, which is the one the driver decides to use for OpenGL rendering. With the FX 1700 + NVS 285 combination, only the FX 1700 is reported, always (I suppose that the NVS 285 does not support this extension, because if it is the only card in use it is still not reported by the extension).
Windows 7 64 with Intel and AMD
This system runs with Windows 7 64-bit and the graphics cards are one Intel HD Graphics 2000 (integrated in the CPU (Sandy Bridge)) and one AMD Radeon HD 6450. In all cases rendering works on both screens, but the rendering GPU varies depending on some variables:
- If the main screen is connected to the AMD and the window is opened in this screen, then the AMD is the renderer.
- If the main screen is connected to the AMD and the window is opened in the other screen, then the renderer is "GDI Generic", which is very slow.
- If the main screen is connected to the Intel, then the Intel is the renderer, independently of where the window is opened.
With this system I have also tried a solution proposed in the OpenGL forums. TL;DR: it's a hacky method to choose the driver used by OpenGL, so it can choose between GPUs that use different drivers, but not between cards that use the same driver. I obtained the following results:
- If the main screen is connected to the AMD, I can choose any GPU as the renderer.
- If the main screen is connected to the Intel, I can choose the Intel as the renderer (useless, as this is automatic), but I get an error if I try to choose the AMD; I think this may be a bug in the driver.