I know it's already asked several times with no clear answer and I already filed a bug to nVIDIA. However, I'm still seeking a better workaround than starting JavaFX in Prism-D3D engine (which immediately allows subsequent OpenGL context to be created via nVIDIA).
Environment:
- nVIDIA 860m, driver 337.88, 340.43, 340.66 (quadro driver)
- Java 8u11 (tested x86/x64 & Java 7 as well)
Tested and failed:
- nVIDIA Profile
- NvOptimusEnablement (custom launcher written in C)
- Calling OpenCL first (custom launcher written in C)
- Calling Cuda first (JCuda, it actually shows nVIDIA name but OpenGL remains unaffected)
Failed APIs:
- JavaFX8 ES2 pipeline (it does function, see https://github.com/AqD/JOGL-FX )
- JOGL 2.1.5
Workarounds:
- JavaFX8 D3D pipeline. All GLContext created after D3D initialization work.
I nailed the problem to a very simple sample, calling realtech-vr OpenGL Extension Viewer (written in .NET). Inside there is a native "infogl.dll" which reads GL information and apparently activates Optimus right after oevClientInitialize.
The weirdness is that, the simplest console program calling infogl.dll works:
Win32.oevSetDriverVersion("10.18.10.3621", 2176);
Win32.oevClientLoadDatabase(File.ReadAllText("C:\\Program Files (x86)\\realtech VR\\OpenGL Extensions Viewer 4.1\\extensions.xml"));
Win32.oevClientInitialize();
for (var i = 0; i <= 9; i++)
{
var tree = Marshal.PtrToStringAnsi(Win32.oevClientGetCapsAndExtTree(i));
Console.WriteLine(tree.Split('\n').First(ln => ln.Contains("text_id=\"357\"")));
}
Console.ReadLine();
But the very same code in Java by JNA doesn't:
infogl.INSTANCE.oevSetDriverVersion("10.18.10.3621", 2176);
String extXml = null;
try {
extXml = new String(
Files.readAllBytes(Paths.get("C:\\Program Files (x86)\\realtech VR\\OpenGL Extensions Viewer 4.1\\extensions.xml")),
"UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
}
infogl.INSTANCE.oevClientLoadDatabase(extXml);
infogl.INSTANCE.oevClientInitialize();
for (int i = 0; i <= 9; i++)
{
String tree = infogl.INSTANCE.oevClientGetCapsAndExtTree(i);
System.out.println(Arrays.asList(tree.split("\\n")).first(ln -> ln.contains("text_id=\"357\"")));
}
And it's unrelated to executable name "java" - I have tried.
The JavaFX D3D solution is unsuitable because it reduces OpenGL FPS by half on AMD Radeon chips - I assume that must be just as bad on nVIDIA ones, and that's why I seek to get it work with ES2 pipeline.
Launching JVM from .NET apparently works (via jni4net). It crashes in nvoglv64.dll at the end of JavaFX finalization through.
I have yet found the real reason that Optimus is activated under .NET...... But it's very likely C/C++ of the same code wouldn't work, since it's exactly what Java version does (JNI calls)
PS: I just verified that "OpenTK" (.NET wrapper of OpenGL) cannot activate Optimus either. I'm totally confused.....