How to get current display mode (resolution, refresh rate) of a monitor/output in DXGI?
Asked Answered
C

3

13

I am creating a multi-monitor full screen DXGI/D3D application. I am enumerating through the available outputs and adapters in preparation of creating their swap chains.

When creating my swap chain using DXGI's IDXGIFactory::CreateSwapChain method, I need to provide a swap chain description which includes a buffer description of type DXGI_MODE_DESC that details the width, height, refresh rate, etc. How can I find out what the output is currently set to (or how can I find out what the display mode of the output currently is)? I don't want to change the user's resolution or refresh rate when I go to full screen with this swap chain.

Crushing answered 23/3, 2013 at 4:19 Comment(0)
C
4

After looking around some more I stumbled upon the EnumDisplaySettings legacy GDI function, which allows me to access the current resolution and refresh rate. Combining this with the IDXGIOutput::FindClosestMatchingMode function I can get pretty close to the current display mode:

void getClosestDisplayModeToCurrent(IDXGIOutput* output, DXGI_MODE_DESC* outCurrentDisplayMode)
{
  DXGI_OUTPUT_DESC outputDesc;
  output->GetDesc(&outputDesc);
  HMONITOR hMonitor = outputDesc.Monitor;
  MONITORINFOEX monitorInfo;
  monitorInfo.cbSize = sizeof(MONITORINFOEX);
  GetMonitorInfo(hMonitor, &monitorInfo);
  DEVMODE devMode;
  devMode.dmSize = sizeof(DEVMODE);
  devMode.dmDriverExtra = 0;
  EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);

  DXGI_MODE_DESC current;
  current.Width = devMode.dmPelsWidth;
  current.Height = devMode.dmPelsHeight;
  bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency;
  current.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency;
  current.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1;
  current.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  current.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  current.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

  output->FindClosestMatchingMode(&current, outCurrentDisplayMode, NULL);
}

...But I don't think that this is really the correct answer because I'm needing to use legacy functions. Is there any way to do this with DXGI to get the exact current display mode rather than using this method?

Crushing answered 31/3, 2013 at 0:27 Comment(1)
Thanks a lot! BTW, the modern way is DwmGetCompositionTimingInfo API, however on Win7 without Aero it fails with DWM_E_COMPOSITIONDISABLEDTenebrous
A
1

I saw solution here: http://www.rastertek.com/dx11tut03.html

In folow part:

   // Now go through all the display modes and find the one that matches the screen width and height.
    // When a match is found store the numerator and denominator of the refresh rate for that monitor.
    for(i=0; i<numModes; i++)
    {
        if(displayModeList[i].Width == (unsigned int)screenWidth)
        {
            if(displayModeList[i].Height == (unsigned int)screenHeight)
            {
                numerator = displayModeList[i].RefreshRate.Numerator;
                denominator = displayModeList[i].RefreshRate.Denominator;
            }
        }
    }

Is my understanding correct, the available resolution is in the displayModeList.

Aseptic answered 26/3, 2013 at 12:41 Comment(1)
Sorry, I'm not looking for the current display mode, not a list of available display modes. But looking at the source code of the link that you provided did lead me to a different set of Windows functions that may help me get to the current display mode...Crushing
B
0
This might be what you are looking for:


            // Get display mode list
            std::vector<DXGI_MODE_DESC*> modeList = GetDisplayModeList(*outputItor);
            for(std::vector<DXGI_MODE_DESC*>::iterator modeItor = modeList.begin(); modeItor != modeList.end(); ++modeItor)
            {
            //  PrintDisplayModeInfo(*modeItor);
            }
        }




std::vector<DXGI_MODE_DESC*> GetDisplayModeList(IDXGIOutput* output)
{
    UINT num = 0;
    DXGI_FORMAT format = DXGI_FORMAT_R32G32B32A32_TYPELESS;
    UINT flags = DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING;

    // Get number of display modes
    output->GetDisplayModeList(format, flags, &num, 0);

    // Get display mode list
    DXGI_MODE_DESC * pDescs = new DXGI_MODE_DESC[num];
    output->GetDisplayModeList(format, flags, &num, pDescs);

    std::vector<DXGI_MODE_DESC*> displayList;
    for(int i = 0; i < num; ++i)
    {
        displayList.push_back(&pDescs[i]);
    }

    return displayList;
}
Brisance answered 30/4, 2015 at 12:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.