Как убедиться, что приложение DirectX 11 использует дискретный графический процессор на ноутбуке с двумя графическими процессорами с C ?

#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 Скриншот приложения, которое не использует графический процессор 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  )
{
…
}