我目前正在开发一个带有DirectX 11的游戏引擎项目,该项目将被编译为动态链接库,并由exe文件调用。我的发动机工作得非常好。但是,我注意到一个奇怪的问题。
我有三个使用此引擎的游戏项目。它们以相同的方式创建和设置,链接器/编译器选项完全相同,并且它们与相同的库链接。但是,当我打开可执行文件时,其中只有一个会在我的笔记本电脑上使用dGPU,而其他两个使用英特尔GPU。
我正在使用Visual Studio 2017和Windows 10 SDK 17763.我没有遍历我的代码中的所有GPU设备,而是使用默认的视频适配器。由于他们使用相同的代码,我认为行为应该是相同的。
这是我如何创建我的ID3D11Device
。
DXGI_SWAP_CHAIN_DESC swapDesc = {};
swapDesc.BufferCount = 2;
swapDesc.BufferDesc.Width = width;
swapDesc.BufferDesc.Height = height;
swapDesc.BufferDesc.RefreshRate.Numerator = 0;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.Flags = 0;
swapDesc.OutputWindow = hWnd;
swapDesc.SampleDesc.Count = 1;
swapDesc.SampleDesc.Quality = 0;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapDesc.Windowed = true;
// Attempt to initialize DirectX
return D3D11CreateDeviceAndSwapChain(
nullptr, // Video adapter (physical GPU) to use, or null for default
D3D_DRIVER_TYPE_HARDWARE, // We want to use the hardware (GPU)
nullptr, // Used when doing software rendering
deviceFlags, // Any special options
nullptr, // Optional array of possible versions we want as fallback
0, // The number of fallback in the above param
D3D11_SDK_VERSION, // Current version of the SDK
&swapDesc, // Address of swap chain options
&swapChain, // Pointer to our Swap Chain pointer
&device, // Pointer to our Device pointer
&dxFeatureLevel, // This will hold the actual feature level the app will use
&context); // Pointer to our Device Context pointer
这是两个EXE的结果。
使用NVIDIA GPU的应用程序的屏幕截图
没有使用NVIDIA GPU的应用程序的屏幕截图
您可以从屏幕截图中看到,在第一个屏幕截图的左上角有一个由NVIDIA GeForce Experience生成的FPS计数器,在右侧有一个通知,表明GeForce Overlay已打开,这意味着该应用程序正在使用NVIDIA GPU。但是,这两个都没有在第二张图片上显示,这意味着该应用程序正在使用英特尔GPU。
对于这些“混合”系统,很大程度上取决于供应商的驱动程序,即用户通过其专有设置UI管理它来“选择正确的GPU”。
在Windows 10(17134)之前,您可以通过在源代码中使用这些“已知”导出来为Win32桌面应用程序提供唯一的编程提示:
// Indicates to hybrid graphics systems to prefer the discrete part by default
extern "C"
{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
使用DXGI 1.6在Windows 10(17134)或更高版本上运行时,您可以使用IDXGIFactory6
通过EnumAdapterByGpuPreference
进行适配器枚举。
ComPtr<IDXGIFactory6> factory6;
HRESULT hr = m_dxgiFactory.As(&factory6);
if (SUCCEEDED(hr))
{
for (UINT adapterIndex = 0;
DXGI_ERROR_NOT_FOUND != factory6->EnumAdapterByGpuPreference(
adapterIndex,
DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
IID_PPV_ARGS(adapter.ReleaseAndGetAddressOf()));
adapterIndex++)
{
…
}
}
else for (UINT adapterIndex = 0;
DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(
adapterIndex,
adapter.ReleaseAndGetAddressOf());
adapterIndex++)
{
…
}