From bbf3cf00316d162dc19a65c4ef302de3d70592f1 Mon Sep 17 00:00:00 2001 From: T-Gander Date: Wed, 19 Aug 2026 00:11:34 -0600 Subject: [PATCH] fix(linux/kms): count CRTCs not planes when assigning monitor index kms_display_names() and display_t::init() each independently counted every active, non-cursor plane as one "monitor" when building/matching the display index. A CRTC with more than one simultaneously-active plane (e.g. gamescope's base + overlay layers) was counted twice by both passes, throwing their indices out of sync with each other and producing duplicate/misnumbered display names. Track counted CRTCs per card in both passes so a CRTC contributes to the index exactly once, regardless of how many active planes it has. --- src/platform/linux/kmsgrab.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index fdf10a92..05c972a1 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -932,6 +933,7 @@ namespace platf { continue; } + std::set counted_crtcs; auto end = std::end(card); for (auto plane = std::begin(card); plane != end; ++plane) { // Skip unused planes @@ -943,8 +945,15 @@ namespace platf { continue; } + // A CRTC can have more than one simultaneously-active plane (e.g. gamescope's + // base + overlay layers). Count each CRTC once so this matches kms_display_names(). + if (counted_crtcs.count(plane->crtc_id)) { + continue; + } + if (monitor != monitor_index) { ++monitor; + counted_crtcs.insert(plane->crtc_id); continue; } @@ -2075,6 +2084,7 @@ namespace platf { } auto crtc_to_monitor = kms::map_crtc_to_monitor(card.monitors(conn_type_count)); + std::set counted_crtcs; auto end = std::end(card); for (auto plane = std::begin(card); plane != end; ++plane) { @@ -2087,6 +2097,12 @@ namespace platf { continue; } + // A CRTC can have more than one simultaneously-active plane (e.g. gamescope's + // base + overlay layers). Count each CRTC once, not once per active plane. + if (counted_crtcs.count(plane->crtc_id)) { + continue; + } + auto fb = card.fb(plane.get()); if (!fb) { BOOST_LOG(error) << "Couldn't get drm fb for plane ["sv << plane->fb_id << "]: "sv << strerror(errno); @@ -2126,6 +2142,7 @@ namespace platf { kms::print(plane.get(), fb.get(), crtc.get()); display_names.emplace_back(std::format("{}-{}", drmModeGetConnectorTypeName(it->second.type), it->second.index)); count++; + counted_crtcs.insert(plane->crtc_id); } cds.emplace_back(kms::card_descriptor_t {