#c #visual-studio-2017 #directx-11
#c #visual-studio-2017 #directx-11
Вопрос:
В настоящее время я работаю над проектом игрового движка с DirectX 11, который будет скомпилирован в динамически связанную библиотеку и вызываться exe-файлом. Мой движок работает отлично. Однако я заметил странную проблему.
У меня есть три игровых проекта, которые используют этот движок. Они создаются и настраиваются одинаковым образом, параметры компоновщика / компилятора полностью совпадают, и они связаны с одними и теми же библиотеками. Но, когда я открываю исполняемые файлы, только один из них будет использовать dGPU на моем ноутбуке, в то время как два других используют графический процессор Intel.
Я использую Visual Studio 2017 и Windows 10 SDK 17763. Я не просматриваю все устройства с графическим процессором в своем коде, а использую видеоадаптер по умолчанию. И поскольку они используют один и тот же код, я предполагаю, что поведение должно быть одинаковым.
Вот как я создаю свой 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
amp;swapDesc, // Address of swap chain options
amp;swapChain, // Pointer to our Swap Chain pointer
amp;device, // Pointer to our Device pointer
amp;dxFeatureLevel, // This will hold the actual feature level the app will use
amp;context); // Pointer to our Device Context pointer
Вот результат двух предыдущих.
Скриншот приложения, использующего графический процессор NVIDIA
Скриншот приложения, которое не использует графический процессор NVIDIA
На скриншотах видно, что в верхнем левом углу первого снимка экрана есть счетчик кадров в секунду, генерируемый NVIDIA GeForce Experience, а справа есть уведомление, указывающее, что оверлей GeForce включен, что означает, что приложение использует графический процессор NVIDIA. Однако ни один из этих двух не показан на втором рисунке, что означает, что приложение использует графический процессор Intel.
Комментарии:
1. Возможно, существует инструмент / приложение, поставляемое с вашей видеокартой / системой, для управления тем, какие приложения используют графический процессор и при каких условиях (подключено к сети или к батарее). Настройки там могут привести к запуску программ на разных графических процессорах.
2. Драйвер Nvidia имеет эвристику для определения, какой графический процессор ему следует использовать ( en.wikipedia.org/wiki/Nvidia_Optimus ). Если вы хотите убедиться, что вы всегда используете дискретный графический процессор, вам придется перечислить свои адаптеры.
Ответ №1:
Для этих «гибридных» систем «выбор правильного графического процессора» во многом зависит от драйвера поставщика, а пользователь управляет им через свой собственный пользовательский интерфейс настроек.
До 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(amp;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 )
{
…
}