mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-08 10:06:28 -05:00
render: respect WLR_DRM_DEVICES in open_drm_render_node
When using WLR_BACKENDS=headless with WLR_DRM_DEVICES, the renderer would ignore the device selection and pick the first available render node. This is problematic for multi-GPU setups where a specific GPU should be used for rendering. Parse WLR_DRM_DEVICES (colon-separated) in open_drm_render_node() to allow selecting which DRM device to use, matching the behavior of the DRM backend. The specified path can be any node type (card, render, primary) and the corresponding render node will be opened.
This commit is contained in:
parent
1f0fb95e3b
commit
67d2fb6ec5
1 changed files with 62 additions and 10 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/interface.h>
|
||||
|
|
@ -113,19 +114,70 @@ static int open_drm_render_node(void) {
|
|||
}
|
||||
|
||||
int fd = -1;
|
||||
for (int i = 0; i < devices_len; i++) {
|
||||
drmDevice *dev = devices[i];
|
||||
if (dev->available_nodes & (1 << DRM_NODE_RENDER)) {
|
||||
const char *name = dev->nodes[DRM_NODE_RENDER];
|
||||
wlr_log(WLR_DEBUG, "Opening DRM render node '%s'", name);
|
||||
fd = open(name, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to open '%s'", name);
|
||||
goto out;
|
||||
|
||||
const char *drm_devices_env = getenv("WLR_DRM_DEVICES");
|
||||
if (drm_devices_env) {
|
||||
char *drm_devices = strdup(drm_devices_env);
|
||||
if (drm_devices == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
char *saveptr;
|
||||
char *token = strtok_r(drm_devices, ":", &saveptr);
|
||||
while (token != NULL) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < devices_len; i++) {
|
||||
drmDevice *dev = devices[i];
|
||||
bool match = false;
|
||||
for (int j = 0; j < DRM_NODE_MAX; j++) {
|
||||
if ((dev->available_nodes & (1 << j)) &&
|
||||
strcmp(dev->nodes[j], token) == 0) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
found = true;
|
||||
if (!(dev->available_nodes & (1 << DRM_NODE_RENDER))) {
|
||||
wlr_log(WLR_DEBUG, "Skipping DRM device '%s': no render node", token);
|
||||
break;
|
||||
}
|
||||
const char *name = dev->nodes[DRM_NODE_RENDER];
|
||||
wlr_log(WLR_DEBUG, "Opening DRM render node '%s' from WLR_DRM_DEVICES", name);
|
||||
fd = open(name, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to open '%s'", name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd >= 0) {
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
wlr_log(WLR_DEBUG, "DRM device '%s' not found", token);
|
||||
}
|
||||
token = strtok_r(NULL, ":", &saveptr);
|
||||
}
|
||||
free(drm_devices);
|
||||
} else {
|
||||
for (int i = 0; i < devices_len; i++) {
|
||||
drmDevice *dev = devices[i];
|
||||
if (dev->available_nodes & (1 << DRM_NODE_RENDER)) {
|
||||
const char *name = dev->nodes[DRM_NODE_RENDER];
|
||||
wlr_log(WLR_DEBUG, "Opening DRM render node '%s'", name);
|
||||
fd = open(name, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to open '%s'", name);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to find any DRM render node");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue