窗口渲染不同的适配器

时间:2017-03-01 14:58:00

标签: directx-11 sharpdx

我有一台带两个适配器的笔记本电脑 - 英特尔和NVIDIA。我正在运行Windows 10,Bios中没有关闭嵌入式英特尔适配器的选项。我可以指定将NVIDIA适配器用于特定应用程序,或者作为所有Direct3D设备创建的默认设置。当我使用英特尔适配器(Windows桌面的固定适配器)时,我在窗口模式下的3D应用程序运行正常。

如果我更改NVIDIA全局设置以强制所有Direct3D设备使用NVIDIA适配器,或者更改我的代码以选择NVIDIA适配器,则代码执行时没有任何错误(我连接了DirectX调试设备)但是没有任何内容在我的内容中呈现窗口。

我认为不可能将Windowed交换链输出连接到不是Windows桌面所使用的适配器的适配器,但我从未见过这一点是明确的。

这意味着在使用Windows桌面嵌入式硬件适配器的笔记本电脑上,我无法在Window中使用功能更强大的NVIDIA适配器,而且必须使用全屏模式。

任何人都可以确认这一点,或建议一种设备创建方法,该方法可以成功地让我在Window中寻址第二个适配器吗?

为清楚起见,我的设备创建代码是;

   private static void initializeDirect3DGraphicsDevice(System.Windows.Forms.Control winFormsControl, out Device device, out SharpDX.DXGI.SwapChain sc)
    {
        SharpDX.DXGI.SwapChainDescription destination = new SharpDX.DXGI.SwapChainDescription()
        {
            BufferCount = 1,
            ModeDescription = new SharpDX.DXGI.ModeDescription(
                winFormsControl.ClientSize.Width,
                winFormsControl.ClientSize.Height,
                new SharpDX.DXGI.Rational(60, 1),
                SharpDX.DXGI.Format.R8G8B8A8_UNorm),
            IsWindowed = true,
            OutputHandle = winFormsControl.Handle,
            SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
            SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
            Usage = SharpDX.DXGI.Usage.RenderTargetOutput
        };

        using (SharpDX.DXGI.Factory1 factory = new SharpDX.DXGI.Factory1())
        {
            // Pick the adapter with teh best video memory allocation - this is the NVIDIA adapter
            List<SharpDX.DXGI.Adapter> adapters = factory.Adapters.OrderBy(item => (long)item.Description.DedicatedVideoMemory).Reverse().ToList();
            SharpDX.DXGI.Adapter bestAdapter = adapters.First();

            foreach(SharpDX.DXGI.Output output in bestAdapter.Outputs)
            {
                System.Diagnostics.Debug.WriteLine("Adapter " + bestAdapter.Description.Description.Substring(0,20) + " output " + output.Description.DeviceName);
            }

            device = new Device(bestAdapter, DeviceCreationFlags.Debug);
            // Uncomment the below to allow the NVIDIA control panel to select the adapter for me.
            //device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.Debug);
            sc = new SharpDX.DXGI.SwapChain(factory, device, destination);
            factory.MakeWindowAssociation(winFormsControl.Handle, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll);

            System.Diagnostics.Debug.WriteLine("Device created with feature level " + device.FeatureLevel + " on adapter " + bestAdapter.Description.Description.Substring(0, 20));
            System.Diagnostics.Debug.WriteLine("");
        }




    }

1 个答案:

答案 0 :(得分:2)

NVIDIA用于管理英特尔集成设备和NVIDIA分立器件的专有技术称为Optimus。 AMD有一种称为PowerXpress的simliar技术。他们都使用驱动程序中的默认Direct3D设备来控制这种行为,这对于作为开发人员来说可能有点奇怪。

  

这些混合图形的硬件解决方案&#39;设备处理从两个GPU合并扫描输出的问题,因此监视器始终只连接到一个设备。

用户始终可以选择强制应用程序通过控制面板使用其中一个,这是最佳用户体验。问题是默认通常不是游戏的好选择。 Win32经典桌面应用程序的解决方案,它可以实现“魔术出口”#39;进入您的EXE,NVIDIA / AMD软件将用于为不在数据库中的应用程序选择默认值:

// Indicates to hybrid graphics systems to prefer the discrete part by default
extern "C"
{
    __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
    __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}

另一个选项是在创建设备时不使用默认适配器并显式枚举它们。这应该有效,但意味着用户不再能够轻松更改正在使用的设备。例如,枚举代码,请参见DeviceResourcesGetHardwareAdapter方法。正如我在上面提到的那样,司机们在列举中乱七八糟,因此魔术出口&#39;可能是最好的通用解决方案。