core: add a rendernode fallback

if no matching rendernode is found, fallback to first available.
This commit is contained in:
Tom Englund 2025-07-19 01:35:31 +02:00
parent 868214c1b7
commit dfedd67148

View file

@ -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);
}