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:
Tested and failed:
Failed APIs:
Workarounds:
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.
using net.sf.jni4net;
using net.sf.jni4net.utils;
...
public static void Main(string[] args)
{
InitializeOpenGL();
var setup = new BridgeSetup();
setup.AddClassPath(@"C:\Program Files\Java\jdk1.8.0_11\demo\javafx_samples\Modena.jar");
setup.AddJVMOption("-Dprism.order=es2");
setup.AddJVMOption("-Dprism.verbose=true");
var env = Bridge.CreateJVM(setup);
[email protected]("Greetings from C# to Java world!");
Console.WriteLine("Initializing...");
var klass = env.FindClass("modena/Modena");
Console.WriteLine("Finding main()...");
var mainMethodId = klass.getMethods().First(m => m.getName().Equals("main")).GetMethodId();
Console.WriteLine("Calling main()...");
env.CallStaticVoidMethod(klass, mainMethodId, Convertor.ParArrayStrongC2JString(env, new string[0]));
Console.WriteLine("Ended, press enter");
Console.ReadLine();
}
protected static void InitializeOpenGL()
{
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\"")));
}
// Optimus should be activated by now!
}
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.....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With