kms: Initialize variable refresh rate CRTC modes

When VRR is not disabled for a GPU, create two variants of every
display mode: one with fixed refresh rate and another with variable
refresh rate.

The variable refresh rate modes are not used yet. They will be used
in a following commit.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
This commit is contained in:
Dor Askayo 2024-01-27 23:59:31 +02:00 committed by Marge Bot
parent 9fcc938075
commit 455ac43e0a
6 changed files with 55 additions and 14 deletions

View File

@ -44,6 +44,12 @@ typedef enum _MetaCrtcModeFlag
META_CRTC_MODE_FLAG_MASK = 0x3fff META_CRTC_MODE_FLAG_MASK = 0x3fff
} MetaCrtcModeFlag; } MetaCrtcModeFlag;
typedef enum _MetaCrtcRefreshRateMode
{
META_CRTC_REFRESH_RATE_MODE_FIXED,
META_CRTC_REFRESH_RATE_MODE_VARIABLE,
} MetaCrtcRefreshRateMode;
typedef struct _MetaCrtcModeInfo typedef struct _MetaCrtcModeInfo
{ {
grefcount ref_count; grefcount ref_count;
@ -51,6 +57,7 @@ typedef struct _MetaCrtcModeInfo
int width; int width;
int height; int height;
float refresh_rate; float refresh_rate;
MetaCrtcRefreshRateMode refresh_rate_mode;
int64_t vblank_duration_us; int64_t vblank_duration_us;
uint32_t pixel_clock_khz; uint32_t pixel_clock_khz;
MetaCrtcModeFlag flags; MetaCrtcModeFlag flags;

View File

@ -40,6 +40,7 @@ meta_crtc_mode_kms_get_kms_mode (MetaCrtcModeKms *mode_kms)
MetaCrtcModeKms * MetaCrtcModeKms *
meta_crtc_mode_kms_new (MetaKmsMode *kms_mode, meta_crtc_mode_kms_new (MetaKmsMode *kms_mode,
MetaCrtcRefreshRateMode refresh_rate_mode,
uint64_t id) uint64_t id)
{ {
const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode); const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode);
@ -53,6 +54,8 @@ meta_crtc_mode_kms_new (MetaKmsMode *kms_mode,
crtc_mode_info->flags = drm_mode->flags; crtc_mode_info->flags = drm_mode->flags;
crtc_mode_info->refresh_rate = crtc_mode_info->refresh_rate =
meta_calculate_drm_mode_refresh_rate (drm_mode); meta_calculate_drm_mode_refresh_rate (drm_mode);
crtc_mode_info->refresh_rate_mode =
refresh_rate_mode;
crtc_mode_info->vblank_duration_us = crtc_mode_info->vblank_duration_us =
meta_calculate_drm_mode_vblank_duration_us (drm_mode); meta_calculate_drm_mode_vblank_duration_us (drm_mode);
crtc_mode_info->pixel_clock_khz = drm_mode->clock; crtc_mode_info->pixel_clock_khz = drm_mode->clock;

View File

@ -31,4 +31,5 @@ G_DECLARE_FINAL_TYPE (MetaCrtcModeKms, meta_crtc_mode_kms,
MetaKmsMode * meta_crtc_mode_kms_get_kms_mode (MetaCrtcModeKms *mode_kms); MetaKmsMode * meta_crtc_mode_kms_get_kms_mode (MetaCrtcModeKms *mode_kms);
MetaCrtcModeKms * meta_crtc_mode_kms_new (MetaKmsMode *kms_mode, MetaCrtcModeKms * meta_crtc_mode_kms_new (MetaKmsMode *kms_mode,
MetaCrtcRefreshRateMode refresh_rate_mode,
uint64_t id); uint64_t id);

View File

@ -163,7 +163,8 @@ compare_outputs (gconstpointer one,
MetaCrtcMode * MetaCrtcMode *
meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms, meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms,
MetaKmsMode *kms_mode) MetaKmsMode *kms_mode,
MetaCrtcRefreshRateMode refresh_rate_mode)
{ {
MetaGpu *gpu = META_GPU (gpu_kms); MetaGpu *gpu = META_GPU (gpu_kms);
GList *l; GList *l;
@ -171,9 +172,21 @@ meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms,
for (l = meta_gpu_get_modes (gpu); l; l = l->next) for (l = meta_gpu_get_modes (gpu); l; l = l->next)
{ {
MetaCrtcModeKms *crtc_mode_kms = l->data; MetaCrtcModeKms *crtc_mode_kms = l->data;
MetaCrtcMode *crtc_mode;
const MetaCrtcModeInfo *crtc_mode_info;
if (meta_kms_mode_equal (kms_mode, if (!meta_kms_mode_equal (kms_mode,
meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms))) meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms)))
continue;
crtc_mode = META_CRTC_MODE (crtc_mode_kms);
crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
g_assert (crtc_mode_info != NULL);
if (refresh_rate_mode != crtc_mode_info->refresh_rate_mode)
continue;
return META_CRTC_MODE (crtc_mode_kms); return META_CRTC_MODE (crtc_mode_kms);
} }
@ -274,7 +287,19 @@ init_modes (MetaGpuKms *gpu_kms)
MetaKmsMode *kms_mode = value; MetaKmsMode *kms_mode = value;
MetaCrtcModeKms *mode; MetaCrtcModeKms *mode;
mode = meta_crtc_mode_kms_new (kms_mode, mode_id); if (!meta_gpu_kms_disable_vrr (gpu_kms))
{
mode = meta_crtc_mode_kms_new (kms_mode,
META_CRTC_REFRESH_RATE_MODE_VARIABLE,
mode_id);
modes = g_list_append (modes, mode);
mode_id++;
}
mode = meta_crtc_mode_kms_new (kms_mode,
META_CRTC_REFRESH_RATE_MODE_FIXED,
mode_id);
modes = g_list_append (modes, mode); modes = g_list_append (modes, mode);
mode_id++; mode_id++;

View File

@ -57,7 +57,8 @@ void meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
MetaKmsUpdate *kms_update); MetaKmsUpdate *kms_update);
MetaCrtcMode * meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms, MetaCrtcMode * meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms,
MetaKmsMode *kms_mode); MetaKmsMode *kms_mode,
MetaCrtcRefreshRateMode refresh_rate_mode);
MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
MetaCrtc *crtc, MetaCrtc *crtc,

View File

@ -179,7 +179,9 @@ add_common_modes (MetaOutputInfo *output_info,
if (is_duplicate) if (is_duplicate)
continue; continue;
crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, fallback_mode); crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms,
fallback_mode,
META_CRTC_REFRESH_RATE_MODE_FIXED);
g_ptr_array_add (array, crtc_mode); g_ptr_array_add (array, crtc_mode);
} }
@ -280,7 +282,9 @@ init_output_modes (MetaOutputInfo *output_info,
MetaKmsMode *kms_mode = l->data; MetaKmsMode *kms_mode = l->data;
MetaCrtcMode *crtc_mode; MetaCrtcMode *crtc_mode;
crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, kms_mode); crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms,
kms_mode,
META_CRTC_REFRESH_RATE_MODE_FIXED);
output_info->modes[i] = crtc_mode; output_info->modes[i] = crtc_mode;
if (kms_mode == kms_preferred_mode) if (kms_mode == kms_preferred_mode)
output_info->preferred_mode = output_info->modes[i]; output_info->preferred_mode = output_info->modes[i];