diff --git a/backend/drm/drm.c b/backend/drm/drm.c index ebea340e0c..01fdbe50c9 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -412,6 +412,41 @@ static bool drm_connector_commit_buffer(struct wlr_output *output) { return true; } +static void drm_connector_enable_adaptive_sync(struct wlr_output *output, + bool enabled) { + struct wlr_drm_connector *conn = get_drm_connector_from_output(output); + struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend); + + struct wlr_drm_crtc *crtc = conn->crtc; + if (!crtc) { + return; + } + + uint64_t vrr_capable; + if (conn->props.vrr_capable == 0 || + !get_drm_prop(drm->fd, conn->id, conn->props.vrr_capable, + &vrr_capable) || !vrr_capable) { + wlr_log(WLR_DEBUG, "Failed to enable adaptive sync: " + "connector '%s' doesn't support VRR", output->name); + return; + } + + if (crtc->props.vrr_enabled == 0) { + wlr_log(WLR_DEBUG, "Failed to enable adaptive sync: " + "CRTC %"PRIu32" doesn't support VRR", crtc->id); + return; + } + + if (drmModeObjectSetProperty(drm->fd, crtc->id, DRM_MODE_OBJECT_CRTC, + crtc->props.vrr_enabled, enabled) != 0) { + wlr_log_errno(WLR_ERROR, "drmModeObjectSetProperty(VRR_ENABLED) failed"); + return; + } + + wlr_log(WLR_DEBUG, "VRR %s on connector '%s'", + enabled ? "enabled" : "disabled", output->name); +} + static bool drm_connector_set_custom_mode(struct wlr_output *output, int32_t width, int32_t height, int32_t refresh); @@ -446,6 +481,11 @@ static bool drm_connector_commit(struct wlr_output *output) { } } + if (output->pending.committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) { + drm_connector_enable_adaptive_sync(output, + output->pending.adaptive_sync_enabled); + } + // TODO: support modesetting with a buffer if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER && !(output->pending.committed & WLR_OUTPUT_STATE_MODE)) { diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 010b71d453..0fafca7b76 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -24,6 +24,7 @@ static const struct prop_info connector_info[] = { { "EDID", INDEX(edid) }, { "PATH", INDEX(path) }, { "link-status", INDEX(link_status) }, + { "vrr_capable", INDEX(vrr_capable) }, #undef INDEX }; @@ -33,6 +34,7 @@ static const struct prop_info crtc_info[] = { { "GAMMA_LUT", INDEX(gamma_lut) }, { "GAMMA_LUT_SIZE", INDEX(gamma_lut_size) }, { "MODE_ID", INDEX(mode_id) }, + { "VRR_ENABLED", INDEX(vrr_enabled) }, { "rotation", INDEX(rotation) }, { "scaling mode", INDEX(scaling_mode) }, #undef INDEX diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index 28f0dbe41a..810a03a3d5 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -16,6 +16,7 @@ union wlr_drm_connector_props { uint32_t dpms; uint32_t link_status; // not guaranteed to exist uint32_t path; + uint32_t vrr_capable; // not guaranteed to exist // atomic-modesetting only @@ -29,6 +30,7 @@ union wlr_drm_crtc_props { // Neither of these are guaranteed to exist uint32_t rotation; uint32_t scaling_mode; + uint32_t vrr_enabled; // atomic-modesetting only