Search code examples
c++windowsgraphicsdirectxdxgi

DXGI monitors enumeration does not give full size for Dell P2715Q monitor


I make DXGI adapters and monitors enumeration. The second monitor connected to my computer is Dell P2715Q, which has 3840*2160 resolution:

Resolution

However, the program reports it as 2560*1440, the second available resolution. Minimal code to reproduce:

int main()
{
IDXGIFactory1* pFactory1;

HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory1));

if (FAILED(hr))
{
    wcout << L"CreateDXGIFactory1 failed. " << endl;
    return 0;
}

for (UINT i = 0;; i++)
{
    IDXGIAdapter1* pAdapter1 = nullptr;

    hr = pFactory1->EnumAdapters1(i, &pAdapter1);

    if (hr == DXGI_ERROR_NOT_FOUND)
    {
        // no more adapters
        break;
    }

    if (FAILED(hr))
    {
        wcout << L"EnumAdapters1 failed. " << endl;
        return 0;
    }

    DXGI_ADAPTER_DESC1 desc;

    hr = pAdapter1->GetDesc1(&desc);

    if (FAILED(hr))
    {
        wcout << L"GetDesc1 failed. " << endl;
        return 0;
    }

    wcout << L"Adapter: " << desc.Description << endl;

    for (UINT j = 0;; j++)
    {
        IDXGIOutput *pOutput = nullptr;

        HRESULT hr = pAdapter1->EnumOutputs(j, &pOutput);

        if (hr == DXGI_ERROR_NOT_FOUND)
        {
            // no more outputs
            break;
        }

        if (FAILED(hr))
        {
            wcout << L"EnumOutputs failed. " << endl;
            return 0;
        }

        DXGI_OUTPUT_DESC desc;

        hr = pOutput->GetDesc(&desc);

        if (FAILED(hr))
        {
            wcout << L"GetDesc1 failed. " << endl;
            return 0;
        }

        wcout << L"  Output: " << desc.DeviceName <<
            L"  (" << desc.DesktopCoordinates.left << L"," << desc.DesktopCoordinates.top << L")-(" <<
            (desc.DesktopCoordinates.right - desc.DesktopCoordinates.left) << L"," << 
            (desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top) << L")" << endl;

    }
}

return 0;
}

Output:

Adapter: Intel(R) Iris(TM) Pro Graphics 6200
   Output: \\.\DISPLAY1  (0,0)-(1920,1200)
   Output: \\.\DISPLAY2  (1920,0)-(2560,1440)

What can cause this behavior: DirectX restrictions, video memory, display adapter, driver, monitor?

Environment:

Windows 10 x64
Intel(R) Iris(TM) Pro Graphics 6200
DELL P2715Q

Solution

  • Your application is treated as non-aware of DPI scaling. The operating system scales the coordinates for you to, presumably, maintain compatibility with legacy applications.

    Let the system know that you are aware of High DPI Desktop Application Development and you will get the coordinates you expect:

    #include <ShellScalingAPI.h>
    
    #pragma comment(lib, "shcore.lib")
    
    int main()
    {
        SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE);
        // there goes your code
    
    Adapter: Intel(R) HD Graphics 4600
      Output: \\.\DISPLAY4  (0,0)-(3840,2160)
      Output: \\.\DISPLAY5  (3840,0)-(3840,2160)
    

    without SetProcessDpiAwareness:

    Adapter: Intel(R) HD Graphics 4600
      Output: \\.\DISPLAY4  (0,0)-(2194,1234)
      Output: \\.\DISPLAY5  (2194,0)-(2194,1234)
    

    Note DXGI_OUTPUT_DESC structure comment on MSDN:

    DesktopCoordinates

    Type: RECT

    A RECT structure containing the bounds of the output in desktop coordinates. Desktop coordinates depend on the dots per inch (DPI) of the desktop. For info about writing DPI-aware Win32 apps, see High DPI.