Search code examples
c++directxdirectx-11dxgi

DXGI Integred adapter


With DXGI, I get a list of all the graphics cards.

IDXGIFactory* factory;
vector<IDXGIAdapter*> all_adapters;

HRESULT result(S_FALSE);
result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
if (FAILED(result))
    return false;

for (int i(0);; i++)
{
    IDXGIAdapter* adpt(nullptr);
    result = factory->EnumAdapters(i, &adpt);
    if (FAILED(result))
        break;
    DXGI_ADAPTER_DESC adesc;
    ZeroMemory(&adesc, sizeof(adesc));
    adpt->GetDesc(&adesc);
    if ((adesc.VendorId == 0x1414) && (adesc.DeviceId == 0x8c)) // no add WARP
    {
        adpt->Release();
        continue;
    }
    all_adapters.push_back(adpt);
}

How to define an integrated graphics card?

I would like to identify a discrete and integrated graphics card.


Solution

  • There's no easy way to identify them beyond vendor ID, and even then you can't be sure that's really what you'd be using due to hybrid graphics solutions like NVidia Optimus or AMD PowerXpress.

    Generally you just use the default device and perhaps add the following to your code to give a hint to any hybrid solution:

    extern "C"
    {
        __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
        __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
    }
    

    UPDATED: In the Windows 10 April 2018 Update, there is now a new IDXGIFactory6 interface that supports a new EnumAdapterByGpuPreference method which lets you enumerate adapters by 'max performance' or 'minimum power'

    ComPtr<IDXGIAdapter1> adapter;
    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++)
        {
            DXGI_ADAPTER_DESC1 desc;
            adapter->GetDesc1(&desc);
    
            if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
            {
                // Don't select the Basic Render Driver adapter.
                continue;
            }
            break;
        }
    }
    else
    {
        for (UINT adapterIndex = 0;
            DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(
                adapterIndex,
                adapter.ReleaseAndGetAddressOf());
                adapterIndex++)
        {
            DXGI_ADAPTER_DESC1 desc;
            adapter->GetDesc1(&desc);
            if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
            {
                // Don't select the Basic Render Driver adapter.
                continue;
            }
            break;
        }        
    }