DirectX 使用 Vortice 从零开始控制台创建 Direct2D1 窗口修改颜色( 四 )


接下来咱也会用到 IDXGIFactory2 提供的功能
// 开始创建工厂创建 D3D 的逻辑var dxgiFactory2 = DXGI.DXGI.CreateDXGIFactory1<DXGI.IDXGIFactory2>();为了让大家方便阅读获取显卡的代码 , 将获取显卡的代码放入到 GetHardwareAdapter 方法
private static IEnumerable<DXGI.IDXGIAdapter1> GetHardwareAdapter(DXGI.IDXGIFactory2 factory) { }先尝试从 IDXGIFactory2 对象获取 IDXGIFactory6 对象
在 DX 的设计上 , 接口都是一个个版本迭代的 , 为了保持兼容性 , 只是新加接口 , 而不是更改原来的接口定义 。也就是获取到的对象 , 也许有在这台设备上的 DX 版本 , 能支持到 IDXGIFactory6 版本 , 通用的做法是调用 QueryInterface* 方法 , 例如 QueryInterfaceOrNull 方法 , 尝试获取到更新的版本的接口对象 。使用封装的 QueryInterfaceOrNull 方法 , 可以在不支持时返回空 , 通过判断返回值即可了解是否支持
DXGI.IDXGIFactory6? factory6 = factory.QueryInterfaceOrNull<DXGI.IDXGIFactory6>();if (factory6 != null){// 这个系统的 DX 支持 IDXGIFactory6 类型}else{// 不支持就不支持咯 , 用旧版本的方式获取显示适配器接口}在 IDXGIFactory6 新加的 EnumAdapterByGpuPreference 方法可以支持传入参数 , 通过参数按照顺序返回显示适配器接口
传入高性能参数开始获取 , 将会按照顺序获取到 DX 认为的高性能排列的顺序
// 先告诉系统 , 要高性能的显卡for (int adapterIndex = 0;factory6.EnumAdapterByGpuPreference(adapterIndex, DXGI.GpuPreference.HighPerformance,out DXGI.IDXGIAdapter1? adapter).Success;adapterIndex++){if (adapter == null){continue;}}再扔掉使用软渲染的 , 扔掉软渲染的这一步只是为了演示如何判断获取到的显示适配器接口是采用软渲染的
// 先告诉系统 , 要高性能的显卡for (int adapterIndex = 0;factory6.EnumAdapterByGpuPreference(adapterIndex, DXGI.GpuPreference.HighPerformance,out DXGI.IDXGIAdapter1? adapter).Success;adapterIndex++){if (adapter == null){continue;}DXGI.AdapterDescription1 desc = adapter.Description1;if ((desc.Flags & DXGI.AdapterFlags.Software) != DXGI.AdapterFlags.None){// Don't select the Basic Render Driver adapter.adapter.Dispose();continue;}}这里可以输出获取到的显示适配器接口的描述 , 可以看看在不同的设备上的输出
Console.WriteLine($"枚举到 {adapter.Description1.Description} 显卡");所有的获取的代码如下
DXGI.IDXGIFactory6? factory6 = factory.QueryInterfaceOrNull<DXGI.IDXGIFactory6>();if (factory6 != null){// 先告诉系统 , 要高性能的显卡for (int adapterIndex = 0;factory6.EnumAdapterByGpuPreference(adapterIndex, DXGI.GpuPreference.HighPerformance,out DXGI.IDXGIAdapter1? adapter).Success;adapterIndex++){if (adapter == null){continue;}DXGI.AdapterDescription1 desc = adapter.Description1;if ((desc.Flags & DXGI.AdapterFlags.Software) != DXGI.AdapterFlags.None){// Don't select the Basic Render Driver adapter.adapter.Dispose();continue;}//factory6.Dispose();Console.WriteLine($"枚举到 {adapter.Description1.Description} 显卡");yield return adapter;}factory6.Dispose();}如果获取不到 , 那就使用旧的方法枚举
// 如果枚举不到 , 那系统返回啥都可以for (int adapterIndex = 0;factory.EnumAdapters1(adapterIndex, out DXGI.IDXGIAdapter1? adapter).Success;adapterIndex++){DXGI.AdapterDescription1 desc = adapter.Description1;if ((desc.Flags & DXGI.AdapterFlags.Software) != DXGI.AdapterFlags.None){// Don't select the Basic Render Driver adapter.adapter.Dispose();continue;}Console.WriteLine($"枚举到 {adapter.Description1.Description} 显卡");yield return adapter;}

经验总结扩展阅读