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:
IDXGIFactory: The root interface responsible for generating DXGI components and discovering hardware adapters.IDXGIAdapter: Represents a physical GPU or software rasterizer.IDXGIOutput: Represents an active display output (such as a physical monitor) connected to an adapter.- 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(orEnumAdapters1onIDXGIFactory1) in a loop, incrementing an integer index starting at0. - The method returns an
IDXGIAdapterpointer 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::GetDescpopulates aDXGI_ADAPTER_DESCstructure 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 at0. - Each successful call returns an
IDXGIOutputinterface corresponding to an active display attached to that GPU. - The loop terminates when
EnumOutputsreturnsDXGI_ERROR_NOT_FOUND. - Calling
IDXGIOutput::GetDescfills aDXGI_OUTPUT_DESCstructure. This contains metadata such as the monitor's device name, desktop coordinates (RECT), rotation state, and the Win32HMONITORhandle.
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:
- Select a Target Format: Choose a display format,
typically
DXGI_FORMAT_R8G8B8A8_UNORMorDXGI_FORMAT_B8G8R8A8_UNORM. - Query Mode Count: Call
IDXGIOutput::GetDisplayModeListpassing the chosen format, flags (such asDXGI_ENUM_MODES_INTERLACEDorDXGI_ENUM_MODES_SCALING), a pointer to aUINTto store the count, andnullptrfor the mode list array. DXGI populates the integer with the total number of supported modes. - Fetch Mode Data: Allocate an array of
DXGI_MODE_DESCstructures sized according to the returned count, then callIDXGIOutput::GetDisplayModeLista 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).