0

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.

Range
  • 416
  • 7
  • 20

1 Answers1

4

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;
    }        
}
Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • Thank you. And how to choose a device during the execution of the program? (for example, it depends on which adapter the user chooses). It is very important for me. – Range Apr 10 '18 at 10:56
  • In theory if you explicitly provide the adapter rather than use the 'default adapter', then the integrated solutions should respect that. There are some vendor control panel behaviors that can override this. – Chuck Walbourn Apr 10 '18 at 17:12
  • I have a value in the control panel "auto-select" But, for example, if I change the value of the variable NvOptimusEnablement to 0x00000001 while the program is running (depends on the choice), then the discrete module is not selected. Only at the compilation stage. Can this be changed? – Range Apr 12 '18 at 12:15
  • 4
    This is a static value looked at by the vendor driver through some whacky process import logic. Is basically a hint and the vendors will not pay attention to it if they have some other setting in their control panel. The point is that you set this if you prefer discrete if available (i.e. a game). If the user wants integrated, then they override it in the control panel. It's not up to the app. – Chuck Walbourn Apr 12 '18 at 19:51
  • 2
    Thanks...it's a very pity :( – Range Apr 13 '18 at 10:04