Integration for DRM variable refresh rate API, utilizing Present extension (v3)

This patch is part of a proposed new interface for supporting variable refresh rate via DRM properties.

=== Changes from v2 ===

  • The Present extension is now used in full to determine window suitability. The callbacks for clip notifications and window destruction has been removed.
  • Per-CRTC support is gone for enabling variable refresh. A window must cover the entire X screen in order to flip so every CRTC must be enabled or disabled at the same time. This occurs during the flip and during the unflip.
  • The "VariableRefresh" X Option is introduced to handle enabling/disabling support for variable refresh. This was needed after the v3 interface changes for the DRM API.
  • The CRTC variable refresh property is now cached when a CRTC is initialized.
  • Function and variable naming has been updated to avoid CamelCase.

=== Adaptive sync and variable refresh rate ===

Adaptive sync is part of the DisplayPort specification and allows for graphics adapters to drive displays with varying frame timings.

Variable refresh rate (VRR) is essentially the same, but defined for HDMI.

=== Use cases for variable refresh rate ===

Variable frame (flip) timings don't align well with fixed refresh rate displays. This results in stuttering, tearing and/or input lag. By adjusting the display refresh rate dynamically these issues can be reduced or eliminated.

However, not all content is suitable for dynamic refresh adaptation. The user may experience "flickering" from differences in panel luminance at different refresh rates. Content that flips at an infrequent rate or demand is more likely to cause large changes in refresh rate that result in flickering.

Userland needs a way to let the driver know when the screen content is suitable for variable refresh rates.

=== DRM API to support variable refresh rates ===

This patch introduces a new API via atomic properties on the DRM connector and CRTC.

The drm_connector has one new optional boolean property:

  • bool vrr_capable - set by the driver if the hardware is capable of supporting variable refresh rates

The drm_crtc has one new default boolean property:

  • bool vrr_enabled - set by userspace indicating that variable refresh rate should be enabled

== Overview for DRM driver developers ===

Driver developers can attach the "vrr_capable" property by calling drm_connector_attach_vrr_capable_property(). This should be done on connectors that could be capable of supporting variable refresh rates (such as DP or HDMI).

The "vrr_capable" can then be updated accordingly by calling drm_connector_set_vrr_capable_property().

The "vrr_enabled" property can be checked from the drm_crtc_state object.

=== Overview for Userland developers ==

The "vrr_enabled" property on the CRTC should be set to true when the CRTC is suitable for variable refresh rates.

To demonstrate the suitability of the API for variable refresh and dynamic adaptation there are additional patches using this API that implement adaptive variable refresh across kernel and userland projects:

These patches enable adaptive variable refresh on X for AMD hardware. Support for variable refresh is disabled by default in xf86-video-amdgpu and will require additional user configuration.

The patches have been tested as working on upstream userland with the GNOME desktop environment under a single monitor setup. They also work on KDE in a single monitor setup with the compositor disabled.

The patches require that suitable applications flip via the Present extension to xf86-video-amdgpu for the entire Screen. Some compositors may interfere with this if they are unable to unredirect the window.

Full implementation details for these changes can be reviewed in their respective mailing lists and the xf86-video-amdgpu GitLab.

=== Previous discussions ===

These patches are based upon feedback from previous threads on the subject. These are linked below for reference: !2 (closed)

Edited by Nicholas Kazlauskas

Merge request reports