[mutter/cherry-pick-43860110] output/kms: Replace common mode bandwidth check with clock check




commit 8e522111b0442912f2423185de2e6ad2dd857486
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Jul 1 13:55:29 2022 +0200

    output/kms: Replace common mode bandwidth check with clock check
    
    The pixel clock determines how fast pixels can be processed. When adding
    non-native common modes, avoid adding modes that exceed the max pixel
    clock frequency of the native modes. Avoiding these avoids potential
    mode setting failures where the GPU can't handle the modeline since the
    configured pixel clock is too fast. This replaces the "bandwidth" check
    which used the number of pixels and refresh rate, which wasn't enough to
    avoid incompatible modes.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2492>
    
    
    (cherry picked from commit 43860110ff0f2485ce043c8b999654c0170c920b)

 src/backends/meta-crtc-mode.h            |  1 +
 src/backends/native/meta-crtc-mode-kms.c |  1 +
 src/backends/native/meta-output-kms.c    | 11 +++--------
 3 files changed, 5 insertions(+), 8 deletions(-)
---
diff --git a/src/backends/meta-crtc-mode.h b/src/backends/meta-crtc-mode.h
index 2ac90e4089..6f16484035 100644
--- a/src/backends/meta-crtc-mode.h
+++ b/src/backends/meta-crtc-mode.h
@@ -55,6 +55,7 @@ typedef struct _MetaCrtcModeInfo
   int height;
   float refresh_rate;
   int64_t vblank_duration_us;
+  uint32_t pixel_clock_khz;
   MetaCrtcModeFlag flags;
 } MetaCrtcModeInfo;
 
diff --git a/src/backends/native/meta-crtc-mode-kms.c b/src/backends/native/meta-crtc-mode-kms.c
index 053367cfd1..e108349c4f 100644
--- a/src/backends/native/meta-crtc-mode-kms.c
+++ b/src/backends/native/meta-crtc-mode-kms.c
@@ -57,6 +57,7 @@ meta_crtc_mode_kms_new (MetaKmsMode *kms_mode,
     meta_calculate_drm_mode_refresh_rate (drm_mode);
   crtc_mode_info->vblank_duration_us =
     meta_calculate_drm_mode_vblank_duration_us (drm_mode);
+  crtc_mode_info->pixel_clock_khz = drm_mode->clock;
 
   crtc_mode_name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN);
   mode_kms = g_object_new (META_TYPE_CRTC_MODE_KMS,
diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c
index fb658f29d4..f60d5ad0dd 100644
--- a/src/backends/native/meta-output-kms.c
+++ b/src/backends/native/meta-output-kms.c
@@ -178,7 +178,7 @@ add_common_modes (MetaOutputInfo *output_info,
   unsigned max_hdisplay = 0;
   unsigned max_vdisplay = 0;
   float max_refresh_rate = 0.0;
-  float max_bandwidth = 0.0;
+  uint32_t max_pixel_clock = 0;
   MetaKmsDevice *kms_device;
   MetaKmsModeFlag flag_filter;
   GList *l;
@@ -187,14 +187,11 @@ add_common_modes (MetaOutputInfo *output_info,
     {
       const MetaCrtcModeInfo *crtc_mode_info =
         meta_crtc_mode_get_info (output_info->modes[i]);
-      float bandwidth;
 
-      bandwidth = crtc_mode_info->refresh_rate * crtc_mode_info->width *
-                  crtc_mode_info->height;
       max_hdisplay = MAX (max_hdisplay, crtc_mode_info->width);
       max_vdisplay = MAX (max_vdisplay, crtc_mode_info->height);
       max_refresh_rate = MAX (max_refresh_rate, crtc_mode_info->refresh_rate);
-      max_bandwidth = MAX (max_bandwidth, bandwidth);
+      max_pixel_clock = MAX (max_pixel_clock, crtc_mode_info->pixel_clock_khz);
     }
 
   max_refresh_rate = MAX (max_refresh_rate, 60.0);
@@ -213,7 +210,6 @@ add_common_modes (MetaOutputInfo *output_info,
     {
       MetaKmsMode *fallback_mode = l->data;
       const drmModeModeInfo *drm_mode;
-      float bandwidth;
       float refresh_rate;
       gboolean is_duplicate = FALSE;
 
@@ -222,11 +218,10 @@ add_common_modes (MetaOutputInfo *output_info,
 
       drm_mode = meta_kms_mode_get_drm_mode (fallback_mode);
       refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
-      bandwidth = refresh_rate * drm_mode->hdisplay * drm_mode->vdisplay;
       if (drm_mode->hdisplay > max_hdisplay ||
           drm_mode->vdisplay > max_vdisplay ||
           refresh_rate > max_refresh_rate ||
-          bandwidth > max_bandwidth)
+          drm_mode->clock > max_pixel_clock)
         continue;
 
       for (i = 0; i < output_info->n_modes; i++)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]