68 lines
3.4 KiB
C#
68 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace VdiDiagnostics {
|
|
public class AdapterResult {
|
|
public string Name;
|
|
public uint VendorId;
|
|
public int DeviceResult;
|
|
}
|
|
|
|
// Enumerate the actual DXGI adapters and create a D3D11 device on each NVIDIA
|
|
// adapter. A WMI/PnP model name alone does not prove that D3D is operational.
|
|
public static class D3DProbe {
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
private struct AdapterDesc {
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Description;
|
|
public uint VendorId, DeviceId, SubSysId, Revision;
|
|
public UIntPtr DedicatedVideoMemory, DedicatedSystemMemory, SharedSystemMemory;
|
|
public long AdapterLuid;
|
|
}
|
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
|
private delegate int EnumAdapters(IntPtr factory, uint index, out IntPtr adapter);
|
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
|
private delegate int GetDesc(IntPtr adapter, out AdapterDesc desc);
|
|
[DllImport("dxgi.dll")]
|
|
private static extern int CreateDXGIFactory1(ref Guid iid, out IntPtr factory);
|
|
[DllImport("d3d11.dll")]
|
|
private static extern int D3D11CreateDevice(IntPtr adapter, uint driverType,
|
|
IntPtr software, uint flags, IntPtr levels, uint levelCount, uint sdkVersion,
|
|
out IntPtr device, out uint featureLevel, out IntPtr context);
|
|
|
|
public static AdapterResult[] Check() {
|
|
var results = new List<AdapterResult>();
|
|
var iid = new Guid("770aae78-f26f-4dba-a829-253c83d1b387");
|
|
IntPtr factory;
|
|
Marshal.ThrowExceptionForHR(CreateDXGIFactory1(ref iid, out factory));
|
|
try {
|
|
var table = Marshal.ReadIntPtr(factory);
|
|
var enumerate = (EnumAdapters)Marshal.GetDelegateForFunctionPointer(
|
|
Marshal.ReadIntPtr(table, 7 * IntPtr.Size), typeof(EnumAdapters));
|
|
for (uint i = 0; i < 32; i++) {
|
|
IntPtr adapter;
|
|
int hr = enumerate(factory, i, out adapter);
|
|
if (hr == unchecked((int)0x887A0002)) break;
|
|
Marshal.ThrowExceptionForHR(hr);
|
|
try {
|
|
var descMethod = (GetDesc)Marshal.GetDelegateForFunctionPointer(
|
|
Marshal.ReadIntPtr(Marshal.ReadIntPtr(adapter), 8 * IntPtr.Size), typeof(GetDesc));
|
|
AdapterDesc desc;
|
|
Marshal.ThrowExceptionForHR(descMethod(adapter, out desc));
|
|
if (desc.VendorId != 0x10de) continue;
|
|
IntPtr device, context;
|
|
uint level;
|
|
hr = D3D11CreateDevice(adapter, 0, IntPtr.Zero, 0, IntPtr.Zero,
|
|
0, 7, out device, out level, out context);
|
|
if (context != IntPtr.Zero) Marshal.Release(context);
|
|
if (device != IntPtr.Zero) Marshal.Release(device);
|
|
results.Add(new AdapterResult { Name = desc.Description,
|
|
VendorId = desc.VendorId, DeviceResult = hr });
|
|
} finally { Marshal.Release(adapter); }
|
|
}
|
|
} finally { Marshal.Release(factory); }
|
|
return results.ToArray();
|
|
}
|
|
}
|
|
}
|