From 43860110ff0f2485ce043c8b999654c0170c920b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 1 Jul 2022 13:55:29 +0200 Subject: [PATCH] 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: --- 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 2ac90e408..6f1648403 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 053367cfd..e108349c4 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 fb658f29d..f60d5ad0d 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++)