From dfedd67148d4128aff99cbd417e9f7d0bd210555 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 19 Jul 2025 01:35:31 +0200 Subject: [PATCH] core: add a rendernode fallback if no matching rendernode is found, fallback to first available. --- src/backend/Session.cpp | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/backend/Session.cpp b/src/backend/Session.cpp index 7fa4604..b8608ad 100644 --- a/src/backend/Session.cpp +++ b/src/backend/Session.cpp @@ -165,13 +165,8 @@ void Aquamarine::CSessionDevice::resolveMatchingRenderNode(struct udev_device* c if (!cardDevice) return; - auto pciParent = udev_device_get_parent_with_subsystem_devtype(cardDevice, "pci", nullptr); - if (!pciParent) - return; - - const char* pciSyspath = udev_device_get_syspath(pciParent); - if (!pciSyspath) - return; + auto pciParent = udev_device_get_parent_with_subsystem_devtype(cardDevice, "pci", nullptr); + const auto* pciSyspath = pciParent ? udev_device_get_syspath(pciParent) : nullptr; struct udev_enumerate* enumerate = udev_enumerate_new(session->udevHandle); if (!enumerate) @@ -183,25 +178,30 @@ void Aquamarine::CSessionDevice::resolveMatchingRenderNode(struct udev_device* c struct udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); struct udev_list_entry* entry = nullptr; + bool matched = false; + udev_list_entry_foreach(entry, devices) { - const char* path = udev_list_entry_get_name(entry); - struct udev_device* dev = udev_device_new_from_syspath(session->udevHandle, path); + const auto* path = udev_list_entry_get_name(entry); + auto dev = udev_device_new_from_syspath(session->udevHandle, path); if (!dev) continue; - const char* devnode = udev_device_get_devnode(dev); - const char* devtype = udev_device_get_devtype(dev); + const auto* devnode = udev_device_get_devnode(dev); + const auto* devtype = udev_device_get_devtype(dev); if (!devnode || !devtype || strcmp(devtype, "drm_minor") != 0 || !strstr(devnode, "renderD")) { udev_device_unref(dev); continue; } - struct udev_device* devParent = udev_device_get_parent_with_subsystem_devtype(dev, "pci", nullptr); - if (devParent && strcmp(udev_device_get_syspath(devParent), pciSyspath) == 0) { + auto devParent = udev_device_get_parent_with_subsystem_devtype(dev, "pci", nullptr); + if (devParent && pciSyspath && strcmp(udev_device_get_syspath(devParent), pciSyspath) == 0) { renderNodeFd = open(devnode, O_RDWR | O_CLOEXEC); if (renderNodeFd < 0) session->backend->log(AQ_LOG_WARNING, std::format("drm: Failed to open matching render node {}", devnode)); + else + matched = true; + udev_device_unref(dev); break; } @@ -209,6 +209,33 @@ void Aquamarine::CSessionDevice::resolveMatchingRenderNode(struct udev_device* c udev_device_unref(dev); } + if (!matched) { + // fallback to the first render node + udev_list_entry_foreach(entry, devices) { + const auto* path = udev_list_entry_get_name(entry); + auto dev = udev_device_new_from_syspath(session->udevHandle, path); + if (!dev) + continue; + + const auto* devnode = udev_device_get_devnode(dev); + const auto* devtype = udev_device_get_devtype(dev); + + if (!devnode || !devtype || strcmp(devtype, "drm_minor") != 0 || !strstr(devnode, "renderD")) { + udev_device_unref(dev); + continue; + } + + renderNodeFd = open(devnode, O_RDWR | O_CLOEXEC); + if (renderNodeFd >= 0) { + session->backend->log(AQ_LOG_WARNING, std::format("drm: No matching render node for {}, falling back to {}", path, devnode)); + udev_device_unref(dev); + break; + } + + udev_device_unref(dev); + } + } + udev_enumerate_unref(enumerate); }