明確な答えがなく、すでに何度か尋ねられていることを知っており、nVIDIAにバグを報告しました。ただし、Prism-D3D エンジンで JavaFX を開始するよりも優れた回避策を探しています (これにより、nVIDIA を介して後続の OpenGL コンテキストをすぐに作成できます)。
環境:
- nVIDIA 860m、ドライバー 337.88、340.43、340.66 (quadro ドライバー)
- Java 8u11 (x86/x64 & Java 7 もテスト済み)
テストして失敗しました:
- nVIDIA プロファイル
- NvOptimusEnablement (C で記述されたカスタム ランチャー)
- 最初に OpenCL を呼び出す (C で記述されたカスタム ランチャー)
- 最初に Cuda を呼び出します (JCuda、実際には nVIDIA 名が表示されますが、OpenGL は影響を受けません)
失敗した API:
- JavaFX8 ES2 パイプライン (機能します。 https://github.com/AqD/JOGL-FXを参照してください)
- JOGL 2.1.5
回避策:
- JavaFX8 D3D パイプライン。D3D 初期化作業後に作成されたすべての GLContext。
realtech-vr OpenGL Extension Viewer (.NET で記述)を呼び出して、非常に単純なサンプルに問題を突き止めました。内部には、GL 情報を読み取り、oevClientInitialize の直後に Optimus をアクティブにするネイティブの「infogl.dll」があります。
奇妙なことに、infogl.dll を呼び出す最も単純なコンソール プログラムが機能します。
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();
しかし、JNAによるJavaのまったく同じコードはそうではありません:
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\"")));
}
そして、それは実行可能ファイル名「java」とは無関係です - 私は試しました。
JavaFX D3D ソリューションは、AMD Radeon チップで OpenGL FPS を半分に削減するため、不適切です。nVIDIA チップでも同じように悪いと思います。そのため、ES2 パイプラインで動作させることを目指しています。