Share via

How do I filter GPUs by type in DXGI (integrated vs dedicated device)?

Noah Thompson 5 Reputation points
2024-12-21T04:19:39.06+00:00

Hello! I have written an extension for the Elgato Stream Deck using C++ and Microsoft DXGI (available here) that queries the utilization of the user's GPU and displays it on the Stream Deck. I need to be able to filter out integrated GPUs and only display dedicated GPU devices for the user to select. Is this possible in DXGI? Or via another Microsoft library?

Windows development | Windows API - Win32
Developer technologies | C++
Developer technologies | C++

A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.

0 comments No comments

2 answers

Sort by: Most helpful
  1. Noah Thompson 5 Reputation points
    2024-12-24T03:42:29.0566667+00:00

    After doing some digging into Microsoft's documentation, I was able to find the DXCore library. This library allowed me to interop with DXGI and filter GPUs by type. This can be achieved like this:

    IDXGIFactory1* factory = nullptr;
    winrt::com_ptr<IDXCoreAdapterFactory> coreFactory;
    
    HRESULT result = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory);
    
    if (FAILED(result)) {
        Log("Failed to create factory object.");
        return;
    }
    
    if (FAILED(DXCoreCreateAdapterFactory(coreFactory.put()))) {
        Log("Failed to create core factory object.");
        return;
    }
    
    UINT index;
    IDXGIAdapter1* adapter = nullptr;
    winrt::com_ptr<IDXCoreAdapter> coreAdapter = nullptr;
    
    
    while (factory->EnumAdapters1(index, &adapter) != DXGI_ERROR_NOT_FOUND) {
        DXGI_ADAPTER_DESC desc;
        adapter->GetDesc(&desc);
    
    	if (FAILED(coreFactory->GetAdapterByLuid(desc.AdapterLuid, coreAdapter.put()))) {
    	    Log("Failed to get core adapter.");
    	    adapter->Release();
    	    ++index;
    	    continue;
    	}
    	
    	if (!coreAdapter->IsPropertySupported(DXCoreAdapterProperty::IsIntegrated) || !coreAdapter->IsPropertySupported(DXCoreAdapterProperty::IsHardware)) {
    	    Log("Adapter does not support required properties.");
    	    adapter->Release();
    	    ++index;
    	    continue;
    	}
    	
    	bool isIntegrated;
    	bool isHardwareAdapter;
    	
    	if (FAILED(coreAdapter->GetProperty(DXCoreAdapterProperty::IsIntegrated, &isIntegrated))) {
    	    Log("Failed to get integrated property.");
    	    adapter->Release();
    	    ++index;
    	    continue;
    	}
    	
    	if (FAILED(coreAdapter->GetProperty(DXCoreAdapterProperty::IsHardware, &isHardwareAdapter))) {
    	    Log("Failed to get hardware property.");
    	    adapter->Release();
    	    ++index;
    	    continue;
    	}
    	
    	if (!isHardwareAdapter) {
    	    Log("Adapter is not a hardware adapter.");
    	    adapter->Release();
    	    ++index;
    	    continue;
    	}
    	
    	if (isIntegrated) {
    	    Log("Adapter is iGPU.");
    	    adapter->Release();
    	    ++index;
    	    continue;
    	}
    }
    

    Please let me know if there is any feedback on this approach! Worked for me with an AMD iGPU.

    Was this answer helpful?

    1 person found this answer helpful.

  2. Castorix31 91,876 Reputation points
    2024-12-21T09:17:48.2666667+00:00

    A way is to test UMA (Unified Memory Architecture).

    This works for me with my old "Intel(R) HD Graphics" integrated GPU :

    IDXGIFactory1* pFactory = NULL;
    HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
    if (SUCCEEDED(hr))
    {
    				IDXGIAdapter1* pAdapter1 = NULL;
    				UINT nAdapterIndex = 0;
    				TCHAR wsText[255];
    				while (pFactory->EnumAdapters1(nAdapterIndex, &pAdapter1) != DXGI_ERROR_NOT_FOUND)
    				{
    					DXGI_ADAPTER_DESC1 desc;
    					pAdapter1->GetDesc1(&desc);		
    
    					wsprintf(wsText, TEXT("GPU n°%d: %s\r\n"), nAdapterIndex, desc.Description);
    					OutputDebugString(wsText);
    
    					ID3D12Device* pD3D12Device = NULL;
    					hr = D3D12CreateDevice(pAdapter1, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&pD3D12Device));
    					if (SUCCEEDED(hr))
    					{
    						D3D12_FEATURE_DATA_ARCHITECTURE1 architecture1 = {};
    						if (SUCCEEDED(pD3D12Device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE1, &architecture1, sizeof(architecture1))))
    						{
    							wsprintf(wsText, TEXT("Type : %s\r\n"), architecture1.UMA ? L"Integrated" : L"Dedicated");
    							OutputDebugString(wsText);						
    						}
    						pD3D12Device->Release();
    					}
    					pAdapter1->Release();
    					nAdapterIndex++;
    				}
    				pFactory->Release();
    }
    
    

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.