提问人:rustak 提问时间:10/24/2023 最后编辑:Simon Mourierrustak 更新时间:10/31/2023 访问量:39
如何区分物理 D3D 适配器与远程桌面协议使用的虚拟适配器?
How to distinguish a physical D3D adapter from a virtual adapter used by the Remote Desktop Protocol?
问:
我目前正在开发一个使用 FFmpeg 解码视频的桌面应用程序 (c#/wpf)。我想让用户选择用于视频解码的适配器。我正在使用 Direct3D 方法列出当前设备上的可用适配器,该适配器工作正常。可用适配器列表如下所示:EnumAdapters
Adapter 0
Description: Intel(R) HD Graphics 630
Vendor ID: 0x8086
Device ID: 0x5912
SubSys ID: 0x86941043
Revision: 4
Luid: 46459
Flags: None
Dedicated Video Memory: 128 MB
Dedicated System Memory: 0 MB
Shared System Memory: 8092 MB
Adapter 2
Description: Microsoft Basic Render Driver
Vendor ID: 0x1414
Device ID: 0x8C
SubSys ID: 0x0
Revision: 0
Luid: 50158
Flags: Software
Dedicated Video Memory: 0 MB
Dedicated System Memory: 0 MB
Shared System Memory: 8092 MB
我注意到,当使用 RDP 时,可用适配器列表中会出现一个额外的适配器。附加适配器具有与物理适配器相同的属性;唯一的区别在于 LUID。输出如下所示:
Adapter 0
Description: Intel(R) HD Graphics 630
Vendor ID: 0x8086
Device ID: 0x5912
SubSys ID: 0x86941043
Revision: 4
Luid: 46459
Flags: None
Dedicated Video Memory: 128 MB
Dedicated System Memory: 0 MB
Shared System Memory: 8092 MB
Adapter 1 // <- additional addapter
Description: Intel(R) HD Graphics 630
Vendor ID: 0x8086
Device ID: 0x5912
SubSys ID: 0x86941043
Revision: 4
Luid: 1322913970
Flags: None
Dedicated Video Memory: 128 MB
Dedicated System Memory: 0 MB
Shared System Memory: 8092 MB
Adapter 2
Description: Microsoft Basic Render Driver
Vendor ID: 0x1414
Device ID: 0x8C
SubSys ID: 0x0
Revision: 0
Luid: 50158
Flags: Software
Dedicated Video Memory: 0 MB
Dedicated System Memory: 0 MB
Shared System Memory: 8092 MB
我知道附加适配器是 RDP 使用的某种虚拟适配器。我都试过了,似乎都适合使用 FFmpeg 进行视频解码。
但是,从 UX 的角度来看,组合框包含两个同名的适配器看起来或感觉都不对。所以我的问题是:如何区分物理适配器和远程桌面协议使用的虚拟适配器?
答:
1赞
rustak
10/31/2023
#1
提供的问题:如何检查 Simon Mourier 是否使用了真正的硬件视频适配器,这帮助我弄清楚了我需要什么。非常感谢!
注册表项“SOFTWARE\Microsoft\DirectX”似乎包含表示实际适配器的子项集合。RDP 使用的其他适配器没有密钥。因此,将 D3D EnumAdapters 的输出与注册表中的适配器列表进行比较就足够了 (并省略注册表中不存在的适配器) 。
我的解决方案如下所示:
using SharpDX.DXGI;
IEnumerable<Adapter1> GetAdapters()
{
var adapters = new Dictionary<long, Adapter1>();
// Retrieve available adapters using SharpDX.DXGI(EnumAdapters)
using var factory = new Factory1();
var adapterCount = factory.GetAdapterCount();
for (int i = 0; i < adapterCount; i++)
{
var adapter = factory.GetAdapter1(i);
adapters[adapter.Description.Luid] = adapter;
}
var directXRegistryKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\DirectX");
foreach (var subKeyName in directXRegistryKey.GetSubKeyNames())
{
var subKey = directXRegistryKey.OpenSubKey(subKeyName);
if (subKey.GetValueKind("AdapterLuid") != RegistryValueKind.QWord)
continue;
if (adapters.TryGetValue((long)subKey.GetValue("AdapterLuid"), out var adapter))
{
// Yield the adapter if it matches luid; omit others
yield return adapter;
}
}
}
我没有找到任何可以证实我的发现的文档,所以请考虑这一点。
评论