In the previous sections, we discussed the execution of rendering commands and video memory management. But at the very end of the graphics stack, how exactly do the rendered pixels appear on the screen smoothly and seamlessly? This brings us to the most revolutionary architecture in the modern Linux display subsystem (DRM/KMS)—Atomic Modesetting.
In this lecture, we'll dive into the display directory of i915 to see how those complex state machines, often spanning thousands of lines, actually work.
1. Why Do We Need Atomic Commit?
In the early Legacy KMS era, display state updates were "fragmented." For example, if a userspace program (such as a Wayland Compositor or X Server) wanted to change the resolution and move the mouse cursor, it needed to call different IOCTLs separately: first set the CRTC (mode setting), then update the Plane (layer parameters), and finally move the Cursor.
The fatal flaws of this design were unpredictability and visible intermediate states:
- Screen tearing/flickering: These three operations might span multiple vertical blanking (Vblank) signals, leading to awkward moments where an old layer is displayed with a new cursor.
- "Getting stuck halfway": If, after setting the CRTC, the driver discovers during the Plane setup that the hardware bandwidth is insufficient, the operation will return an error. However, the CRTC has already been modified and is difficult to roll back, ultimately resulting in a black screen.
To solve this problem, the kernel introduced Atomic KMS. Its core idea is to package all display states (configurations of CRTCs, Planes, and Connectors) into a single "Transaction." The driver either applies the entire state to the hardware perfectly in one go, or rejects it outright during the check phase, ensuring absolute consistency of the hardware state—this is the essence of "Atomicity."
2. Two-Phase Design: Check and Commit
In i915, the entire atomic update process is strictly divided into two phases: atomic_check and atomic_commit.
Phase One: State Validation (intel_atomic_check)
When userspace submits a packaged new state, the entry function is intel_atomic_check.
During this phase, the driver must never modify any actual hardware registers. Its sole task is to simulate in software:
- Recompute PLL clocks (checking if the required pixel frequency can be generated).
- Calculate display bandwidth (checking if memory bandwidth can support a 4K 144Hz display with multiple UI layers).
- If all validations pass, return 0; if even a single hardware constraint cannot be met, return an error code directly (such as
-EINVALor-ENOSPC). The userspace application can then lower its requirements (e.g., reduce the refresh rate) and try again based on this feedback.
Phase Two: Hardware Commit (intel_atomic_commit)
After validation passes, the kernel asynchronously calls intel_atomic_commit (which ultimately lands in intel_atomic_commit_tail).
This is an extremely precise state machine that dismantles the old state and assembles the new state in a strict order:
- Wait for the rendering of the previous frame to complete (depending on
dma_fenceas discussed earlier). - Disable Planes and CRTCs that are no longer in use.
- Update global display clocks and DDI interfaces.
- Reallocate DDB and Watermarks (detailed later).
- Enable new CRTCs and Planes.
3. The Carrier of Hardware Constraints: intel_crtc_state
In the i915 source file intel_display_types.h, there is a massive structure struct intel_crtc_state. It holds the complete blueprint for mapping a display pipe from software abstraction to hardware registers.
Among its contents, Watermarks (WM) and DDB (Display Data Buffer) are the key hardware constraints that determine whether an Atomic commit can succeed.
3.1 The Lifeline of Supply and Demand: Watermarks (WM)
The GPU's display engine needs to continuously read pixels from video memory and send them to the monitor. If the memory read speed cannot keep up with the monitor's scanning speed, the screen will show visual artifacts (Underrun).
To prevent this, the display engine has internal FIFO buffers. Watermarks are the "warning levels" for these buffers:
- The driver needs to precisely calculate these based on the current resolution, color format (e.g., NV12 or ARGB), and memory latency (System Memory is slow, LMEM is fast).
- When the data in the FIFO drops below this watermark level, the hardware must immediately issue an urgent memory read request.
- In the
wmfield ofintel_crtc_state, i915 meticulously calculates WMs at various levels (such as raw, optimal, intermediate) to ensure that the pixel stream never runs dry.
3.2 Precise Partitioning of SRAM: DDB Allocation
The total size of the high-speed SRAM buffer (DDB) inside the display engine is fixed. If you have multiple displays (Pipes) and multiple layers (Planes) working simultaneously, these DDB blocks must be precisely partitioned.
-
Dynamic Reallocation: If you suddenly add a video overlay plane to a running 4K monitor, this triggers an Atomic commit.
intel_atomic_checkmust recalculate the DDB (struct skl_ddb_entry). -
Seamless Transition: If you forcibly snatch DDB from an active layer to give it to a new one, it might cause screen tearing. Therefore, in
intel_atomic_commit, you will see careful calls likeintel_dbuf_mbus_pre_ddb_update()andpost_ddb_update(), ensuring that the DDB re-partitioning transitions smoothly during the vertical blanking interval (Vblank).
If, during the atomic_check phase, the driver finds that even squeezing all available DDB cannot meet the newly requested resolution and layer combination, it will directly reject this update.
Summary
Atomic Modesetting has completely ended the flickering and tearing problems that once plagued Linux graphical interfaces. Through a strict two-phase design (a validation phase that does not touch hardware, and a meticulously ordered commit phase), i915 perfectly encapsulates complex hardware constraints—including clocks, bandwidth, Watermarks, and DDB allocation—into a single atomic transaction.
In the next lecture, we will move into Part 5 and explore how the driver controls the power consumption and sleep states of this "performance beast."
Top comments (0)