How DXGI Enumerates Outputs and Resolutions

DirectX Graphics Infrastructure (DXGI) acts as the bridge between graphics hardware, the operating system, and Direct3D rendering pipelines. To identify connected monitors and determine their supported screen resolutions, DXGI uses an object hierarchy starting from a core factory interface down to individual display modes. This article explains the exact sequence of interfaces and methods DXGI utilizes to detect physical graphics adapters, enumerate monitor outputs attached to those adapters, and retrieve comprehensive lists of compatible resolutions, refresh rates, and color formats.

The DXGI Object Hierarchy

DXGI structures hardware enumeration through four primary objects:

  1. IDXGIFactory: The root interface responsible for generating DXGI components and discovering hardware adapters.
  2. IDXGIAdapter: Represents a physical GPU or software rasterizer.
  3. IDXGIOutput: Represents an active display output (such as a physical monitor) connected to an adapter.
  4. Display Modes (DXGI_MODE_DESC): Data structures detailing the supported resolutions, refresh rates, scanline order, and pixel formats available on an output.

Step 1: Initialize the DXGI Factory

Enumeration begins by initializing the DXGI factory. Modern applications use CreateDXGIFactory1 or CreateDXGIFactory2 to create an IDXGIFactory1 or IDXGIFactory2 interface. This factory provides the initial access point to query the underlying hardware configuration.

Step 2: Enumerate Display Adapters (GPUs)

Once the factory exists, you query the system's graphics adapters:

  • Call IDXGIFactory::EnumAdapters (or EnumAdapters1 on IDXGIFactory1) in a loop, incrementing an integer index starting at 0.
  • The method returns an IDXGIAdapter pointer for each detected GPU.
  • When the index exceeds the number of available adapters, the method returns DXGI_ERROR_NOT_FOUND, signaling the end of the adapter list.
  • Calling IDXGIAdapter::GetDesc populates a DXGI_ADAPTER_DESC structure containing the GPU name, vendor ID, device ID, and dedicated video memory.

Step 3: Enumerate Physical Monitor Outputs

Because physical monitors are driven by specific GPUs, outputs are enumerated through their respective adapter:

  • Call IDXGIAdapter::EnumOutputs, passing an integer index starting at 0.
  • Each successful call returns an IDXGIOutput interface corresponding to an active display attached to that GPU.
  • The loop terminates when EnumOutputs returns DXGI_ERROR_NOT_FOUND.
  • Calling IDXGIOutput::GetDesc fills a DXGI_OUTPUT_DESC structure. This contains metadata such as the monitor's device name, desktop coordinates (RECT), rotation state, and the Win32 HMONITOR handle.

Step 4: Retrieve Supported Resolutions and Display Modes

Display resolutions and refresh rates vary depending on the chosen color format. DXGI queries display modes per format:

  1. Select a Target Format: Choose a display format, typically DXGI_FORMAT_R8G8B8A8_UNORM or DXGI_FORMAT_B8G8R8A8_UNORM.
  2. Query Mode Count: Call IDXGIOutput::GetDisplayModeList passing the chosen format, flags (such as DXGI_ENUM_MODES_INTERLACED or DXGI_ENUM_MODES_SCALING), a pointer to a UINT to store the count, and nullptr for the mode list array. DXGI populates the integer with the total number of supported modes.
  3. Fetch Mode Data: Allocate an array of DXGI_MODE_DESC structures sized according to the returned count, then call IDXGIOutput::GetDisplayModeList a second time, passing the array pointer to populate the list.

Interpreting the Mode Descriptions

Each entry in the retrieved DXGI_MODE_DESC array contains the exact parameters required by the display hardware:

  • Width and Height: The pixel dimensions of the resolution (e.g., 1920x1080).
  • RefreshRate: Expressed as a rational fraction (DXGI_RATIONAL) with a numerator and denominator (e.g., 60000/1001 for 59.94 Hz or 60/1 for 60 Hz).
  • Format: The DXGI surface pixel format used for rendering.
  • ScanlineOrdering: Indicates progressive or interlaced rendering.
  • Scaling: Specifies how the monitor handles scaling when the target mode does not match the native panel resolution (e.g., centered, stretched, or unscaled).