首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java/OpenGL下激活nVIDIA Optimus?

在Java/OpenGL下激活nVIDIA Optimus?
EN

Stack Overflow用户
提问于 2014-08-18 16:25:56
回答 1查看 738关注 0票数 2

我知道它已经被问了好几次,没有得到明确的回答,我已经向nVIDIA提交了一个bug。然而,我仍然在寻找一个比在Prism中启动JavaFX更好的解决方案-D3D引擎(它立即允许通过nVIDIA创建后续的OpenGL上下文)。

环境:

  • nVIDIA 860米,驱动器337.88,340.43,340.66 (象限驱动)
  • Java 8u11 (也测试了x86/x64和Java 7)

经过测试和失败:

  • nVIDIA配置文件
  • NvOptimusEnablement (用C语言编写的自定义发射器)
  • 首先调用OpenCL (用C编写的自定义启动程序)
  • 首先调用Cuda (JCuda,它实际上显示了nVIDIA名称,但OpenGL没有受到影响)

失败的API:

解决办法:

  • JavaFX8 D3D管道所有GLContext都是在D3D初始化工作之后创建的。

我用一个非常简单的例子解决了这个问题,调用realtech-vr OpenGL扩展查看器 (用.NET编写)。在里面有一个本地的"infogl.dll“,它读取GL信息并在oevClientInitialize之后激活Optimus。

奇怪的是,调用infogl.dll的最简单的控制台程序可以工作:

代码语言:javascript
复制
    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中的相同代码

代码语言:javascript
复制
    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解决方案是不合适的,因为它将OpenGL FPS在AMD芯片上减少了一半--我想这在nVIDIA芯片上肯定也一样糟糕,这就是为什么我试图让它与ES2管道一起工作的原因。

EN

回答 1

Stack Overflow用户

发布于 2014-08-18 18:09:45

从.NET启动JVM显然有效(通过jni4net)。它在nvoglv64.dll中的nvoglv64.dll中崩溃,最后通过JavaFX完成。

代码语言:javascript
复制
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);
        java.lang.System.@out.println("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!
    }

我还没有找到擎天柱在.NET下激活的真正原因.但这很可能是相同代码的C/C++无法工作,因为这正是Java版本所做的(JNI调用)

PS:我刚刚验证了"OpenTK“(OpenGL的.NET包装器)也不能激活Optimus。我完全糊涂了.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25367851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档