backend/drm: Drop parent drm device

Compositors should instead blit to secondary drm devices themselves.
This commit is contained in:
Alexander Orzechowski 2024-10-13 11:51:41 -04:00
parent 2cca0086fb
commit e319909294
10 changed files with 13 additions and 311 deletions

View file

@ -258,7 +258,7 @@ static struct wlr_backend *attempt_drm_backend(struct wlr_backend *backend, stru
struct wlr_backend *primary_drm = NULL; struct wlr_backend *primary_drm = NULL;
for (size_t i = 0; i < (size_t)num_gpus; ++i) { for (size_t i = 0; i < (size_t)num_gpus; ++i) {
struct wlr_backend *drm = wlr_drm_backend_create(session, gpus[i], primary_drm); struct wlr_backend *drm = wlr_drm_backend_create(session, gpus[i]);
if (!drm) { if (!drm) {
wlr_log(WLR_ERROR, "Failed to create DRM backend"); wlr_log(WLR_ERROR, "Failed to create DRM backend");
continue; continue;

View file

@ -275,9 +275,9 @@ bool drm_atomic_connector_prepare(struct wlr_drm_connector_state *state, bool mo
} }
int in_fence_fd = -1; int in_fence_fd = -1;
if (state->wait_timeline != NULL) { if (state->base->committed & WLR_OUTPUT_STATE_WAIT_TIMELINE) {
in_fence_fd = wlr_drm_syncobj_timeline_export_sync_file(state->wait_timeline, in_fence_fd = wlr_drm_syncobj_timeline_export_sync_file(state->base->wait_timeline,
state->wait_point); state->base->wait_point);
if (in_fence_fd < 0) { if (in_fence_fd < 0) {
return false; return false;
} }

View file

@ -49,14 +49,9 @@ static void backend_destroy(struct wlr_backend *backend) {
wl_list_remove(&drm->session_destroy.link); wl_list_remove(&drm->session_destroy.link);
wl_list_remove(&drm->session_active.link); wl_list_remove(&drm->session_active.link);
wl_list_remove(&drm->parent_destroy.link);
wl_list_remove(&drm->dev_change.link); wl_list_remove(&drm->dev_change.link);
wl_list_remove(&drm->dev_remove.link); wl_list_remove(&drm->dev_remove.link);
if (drm->parent) {
finish_drm_renderer(&drm->mgpu_renderer);
}
finish_drm_resources(drm); finish_drm_resources(drm);
struct wlr_drm_fb *fb, *fb_tmp; struct wlr_drm_fb *fb, *fb_tmp;
@ -104,11 +99,6 @@ bool wlr_backend_is_drm(struct wlr_backend *b) {
return b->impl == &backend_impl; return b->impl == &backend_impl;
} }
struct wlr_backend *wlr_drm_backend_get_parent(struct wlr_backend *backend) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
return drm->parent ? &drm->parent->backend : NULL;
}
static void handle_session_active(struct wl_listener *listener, void *data) { static void handle_session_active(struct wl_listener *listener, void *data) {
struct wlr_drm_backend *drm = struct wlr_drm_backend *drm =
wl_container_of(listener, drm, session_active); wl_container_of(listener, drm, session_active);
@ -159,16 +149,8 @@ static void handle_session_destroy(struct wl_listener *listener, void *data) {
backend_destroy(&drm->backend); backend_destroy(&drm->backend);
} }
static void handle_parent_destroy(struct wl_listener *listener, void *data) { struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session, struct wlr_device *dev) {
struct wlr_drm_backend *drm =
wl_container_of(listener, drm, parent_destroy);
backend_destroy(&drm->backend);
}
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
struct wlr_device *dev, struct wlr_backend *parent) {
assert(session && dev); assert(session && dev);
assert(!parent || wlr_backend_is_drm(parent));
char *name = drmGetDeviceNameFromFd2(dev->fd); char *name = drmGetDeviceNameFromFd2(dev->fd);
if (name == NULL) { if (name == NULL) {
@ -201,15 +183,6 @@ struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
drm->fd = dev->fd; drm->fd = dev->fd;
drm->name = name; drm->name = name;
if (parent != NULL) {
drm->parent = get_drm_backend_from_backend(parent);
drm->parent_destroy.notify = handle_parent_destroy;
wl_signal_add(&parent->events.destroy, &drm->parent_destroy);
} else {
wl_list_init(&drm->parent_destroy.link);
}
drm->dev_change.notify = handle_dev_change; drm->dev_change.notify = handle_dev_change;
wl_signal_add(&dev->events.change, &drm->dev_change); wl_signal_add(&dev->events.change, &drm->dev_change);
@ -234,58 +207,19 @@ struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
goto error_event; goto error_event;
} }
if (drm->parent) {
if (!init_drm_renderer(drm, &drm->mgpu_renderer)) {
wlr_log(WLR_ERROR, "Failed to initialize renderer");
goto error_resources;
}
// We'll perform a multi-GPU copy for all submitted buffers, we need
// to be able to texture from them
struct wlr_renderer *renderer = drm->mgpu_renderer.wlr_rend;
const struct wlr_drm_format_set *texture_formats =
wlr_renderer_get_texture_formats(renderer, WLR_BUFFER_CAP_DMABUF);
if (texture_formats == NULL) {
wlr_log(WLR_ERROR, "Failed to query renderer texture formats");
goto error_mgpu_renderer;
}
// Forbid implicit modifiers, because their meaning changes from one
// GPU to another.
for (size_t i = 0; i < texture_formats->len; i++) {
const struct wlr_drm_format *fmt = &texture_formats->formats[i];
for (size_t j = 0; j < fmt->len; j++) {
uint64_t mod = fmt->modifiers[j];
if (mod == DRM_FORMAT_MOD_INVALID) {
continue;
}
wlr_drm_format_set_add(&drm->mgpu_formats, fmt->format, mod);
}
}
}
drm->backend.features.timeline = drm->iface != &legacy_iface; drm->backend.features.timeline = drm->iface != &legacy_iface;
if (drm->parent) {
drm->backend.features.timeline = drm->backend.features.timeline &&
drm->mgpu_renderer.wlr_rend->features.timeline;
}
drm->session_destroy.notify = handle_session_destroy; drm->session_destroy.notify = handle_session_destroy;
wl_signal_add(&session->events.destroy, &drm->session_destroy); wl_signal_add(&session->events.destroy, &drm->session_destroy);
return &drm->backend; return &drm->backend;
error_mgpu_renderer:
finish_drm_renderer(&drm->mgpu_renderer);
error_resources:
finish_drm_resources(drm);
error_event: error_event:
wl_list_remove(&drm->session_active.link); wl_list_remove(&drm->session_active.link);
wl_event_source_remove(drm->drm_event); wl_event_source_remove(drm->drm_event);
error_fd: error_fd:
wl_list_remove(&drm->dev_remove.link); wl_list_remove(&drm->dev_remove.link);
wl_list_remove(&drm->dev_change.link); wl_list_remove(&drm->dev_change.link);
wl_list_remove(&drm->parent_destroy.link);
wlr_session_close_file(drm->session, dev); wlr_session_close_file(drm->session, dev);
free(drm->name); free(drm->name);
free(drm); free(drm);

View file

@ -65,15 +65,6 @@ bool check_drm_features(struct wlr_drm_backend *drm) {
return false; return false;
} }
if (drm->parent) {
if (drmGetCap(drm->parent->fd, DRM_CAP_PRIME, &cap) ||
!(cap & DRM_PRIME_CAP_EXPORT)) {
wlr_log(WLR_ERROR,
"PRIME export not supported on primary GPU");
return false;
}
}
if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) {
wlr_log(WLR_ERROR, "DRM universal planes unsupported"); wlr_log(WLR_ERROR, "DRM universal planes unsupported");
return false; return false;
@ -369,8 +360,6 @@ static void drm_plane_finish_surface(struct wlr_drm_plane *plane) {
drm_fb_clear(&plane->queued_fb); drm_fb_clear(&plane->queued_fb);
drm_fb_clear(&plane->current_fb); drm_fb_clear(&plane->current_fb);
finish_drm_surface(&plane->mgpu_surf);
} }
void finish_drm_resources(struct wlr_drm_backend *drm) { void finish_drm_resources(struct wlr_drm_backend *drm) {
@ -709,52 +698,8 @@ static bool drm_connector_state_update_primary_fb(struct wlr_drm_connector *conn
struct wlr_drm_plane *plane = crtc->primary; struct wlr_drm_plane *plane = crtc->primary;
struct wlr_buffer *source_buf = state->base->buffer; struct wlr_buffer *source_buf = state->base->buffer;
struct wlr_drm_syncobj_timeline *wait_timeline = NULL; bool ok = drm_fb_import(&state->primary_fb, drm, source_buf,
uint64_t wait_point = 0;
if (state->base->committed & WLR_OUTPUT_STATE_WAIT_TIMELINE) {
wait_timeline = state->base->wait_timeline;
wait_point = state->base->wait_point;
}
assert(state->wait_timeline == NULL);
struct wlr_buffer *local_buf;
if (drm->parent) {
struct wlr_drm_format format = {0};
if (!drm_plane_pick_render_format(plane, &format, &drm->mgpu_renderer)) {
wlr_log(WLR_ERROR, "Failed to pick primary plane format");
return false;
}
// TODO: fallback to modifier-less buffer allocation
bool ok = init_drm_surface(&plane->mgpu_surf, &drm->mgpu_renderer,
source_buf->width, source_buf->height, &format);
wlr_drm_format_finish(&format);
if (!ok) {
return false;
}
local_buf = drm_surface_blit(&plane->mgpu_surf, source_buf,
wait_timeline, wait_point);
if (local_buf == NULL) {
return false;
}
if (plane->mgpu_surf.timeline != NULL) {
state->wait_timeline = wlr_drm_syncobj_timeline_ref(plane->mgpu_surf.timeline);
state->wait_point = plane->mgpu_surf.point;
}
} else {
local_buf = wlr_buffer_lock(source_buf);
if (wait_timeline != NULL) {
state->wait_timeline = wlr_drm_syncobj_timeline_ref(wait_timeline);
state->wait_point = wait_point;
}
}
bool ok = drm_fb_import(&state->primary_fb, drm, local_buf,
&plane->formats); &plane->formats);
wlr_buffer_unlock(local_buf);
if (!ok) { if (!ok) {
wlr_drm_conn_log(conn, WLR_DEBUG, wlr_drm_conn_log(conn, WLR_DEBUG,
"Failed to import buffer for scan-out"); "Failed to import buffer for scan-out");
@ -769,7 +714,7 @@ static bool drm_connector_set_pending_layer_fbs(struct wlr_drm_connector *conn,
struct wlr_drm_backend *drm = conn->backend; struct wlr_drm_backend *drm = conn->backend;
struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_crtc *crtc = conn->crtc;
if (!crtc || drm->parent) { if (!crtc) {
return false; return false;
} }
@ -828,12 +773,6 @@ static bool drm_connector_prepare(struct wlr_drm_connector_state *conn_state, bo
return false; return false;
} }
if (test_only && conn->backend->parent) {
// If we're running as a secondary GPU, we can't perform an atomic
// commit without blitting a buffer.
return true;
}
if (state->committed & WLR_OUTPUT_STATE_BUFFER) { if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
if (!drm_connector_state_update_primary_fb(conn, conn_state)) { if (!drm_connector_state_update_primary_fb(conn, conn_state)) {
return false; return false;
@ -898,13 +837,6 @@ static bool drm_connector_commit_state(struct wlr_drm_connector *conn,
goto out; goto out;
} }
if (test_only && conn->backend->parent) {
// If we're running as a secondary GPU, we can't perform an atomic
// commit without blitting a buffer.
ok = true;
goto out;
}
if (!pending.active && conn->crtc == NULL) { if (!pending.active && conn->crtc == NULL) {
// Disabling an already-disabled connector // Disabling an already-disabled connector
ok = true; ok = true;
@ -1094,28 +1026,7 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
return false; return false;
} }
struct wlr_buffer *local_buf; struct wlr_buffer *local_buf = wlr_buffer_lock(buffer);
if (drm->parent) {
struct wlr_drm_format format = {0};
if (!drm_plane_pick_render_format(plane, &format, &drm->mgpu_renderer)) {
wlr_log(WLR_ERROR, "Failed to pick cursor plane format");
return false;
}
bool ok = init_drm_surface(&plane->mgpu_surf, &drm->mgpu_renderer,
buffer->width, buffer->height, &format);
wlr_drm_format_finish(&format);
if (!ok) {
return false;
}
local_buf = drm_surface_blit(&plane->mgpu_surf, buffer, NULL, 0);
if (local_buf == NULL) {
return false;
}
} else {
local_buf = wlr_buffer_lock(buffer);
}
bool ok = drm_fb_import(&conn->cursor_pending_fb, drm, local_buf, bool ok = drm_fb_import(&conn->cursor_pending_fb, drm, local_buf,
&plane->formats); &plane->formats);
@ -1209,9 +1120,6 @@ static const struct wlr_drm_format_set *drm_connector_get_cursor_formats(
if (!plane) { if (!plane) {
return NULL; return NULL;
} }
if (conn->backend->parent) {
return &conn->backend->mgpu_formats;
}
return &plane->formats; return &plane->formats;
} }
@ -1238,9 +1146,6 @@ static const struct wlr_drm_format_set *drm_connector_get_primary_formats(
if (!drm_connector_alloc_crtc(conn)) { if (!drm_connector_alloc_crtc(conn)) {
return NULL; return NULL;
} }
if (conn->backend->parent) {
return &conn->backend->mgpu_formats;
}
return &conn->crtc->primary->formats; return &conn->crtc->primary->formats;
} }
@ -1995,13 +1900,6 @@ bool commit_drm_device(struct wlr_drm_backend *drm,
modeset |= output_state->base.allow_reconfiguration; modeset |= output_state->base.allow_reconfiguration;
} }
if (test_only && drm->parent) {
// If we're running as a secondary GPU, we can't perform an atomic
// commit without blitting a buffer.
ok = true;
goto out;
}
uint32_t flags = 0; uint32_t flags = 0;
if (!test_only) { if (!test_only) {
flags |= DRM_MODE_PAGE_FLIP_EVENT; flags |= DRM_MODE_PAGE_FLIP_EVENT;
@ -2034,7 +1932,8 @@ static void handle_page_flip(int fd, unsigned seq,
conn->pending_page_flip = NULL; conn->pending_page_flip = NULL;
} }
uint32_t present_flags = WLR_OUTPUT_PRESENT_HW_CLOCK | WLR_OUTPUT_PRESENT_HW_COMPLETION; uint32_t present_flags = WLR_OUTPUT_PRESENT_HW_CLOCK | WLR_OUTPUT_PRESENT_HW_COMPLETION |
WLR_OUTPUT_PRESENT_ZERO_COPY;
if (!page_flip->async) { if (!page_flip->async) {
present_flags |= WLR_OUTPUT_PRESENT_VSYNC; present_flags |= WLR_OUTPUT_PRESENT_VSYNC;
} }
@ -2069,14 +1968,6 @@ static void handle_page_flip(int fd, unsigned seq,
drm_fb_move(&layer->current_fb, &layer->queued_fb); drm_fb_move(&layer->current_fb, &layer->queued_fb);
} }
/* Don't report ZERO_COPY in multi-gpu situations, because we had to copy
* data between the GPUs, even if we were using the direct scanout
* interface.
*/
if (!drm->parent) {
present_flags |= WLR_OUTPUT_PRESENT_ZERO_COPY;
}
struct wlr_output_event_present present_event = { struct wlr_output_event_present present_event = {
/* The DRM backend guarantees that the presentation event will be for /* The DRM backend guarantees that the presentation event will be for
* the last submitted frame. */ * the last submitted frame. */

View file

@ -25,8 +25,7 @@ static void handle_add_drm_card(struct wl_listener *listener, void *data) {
} }
wlr_log(WLR_DEBUG, "Creating DRM backend for %s after hotplug", event->path); wlr_log(WLR_DEBUG, "Creating DRM backend for %s after hotplug", event->path);
struct wlr_backend *child_drm = wlr_drm_backend_create(backend_monitor->session, struct wlr_backend *child_drm = wlr_drm_backend_create(backend_monitor->session, dev);
dev, backend_monitor->primary_drm);
if (!child_drm) { if (!child_drm) {
wlr_log(WLR_ERROR, "Failed to create DRM backend after hotplug"); wlr_log(WLR_ERROR, "Failed to create DRM backend after hotplug");
return; return;

View file

@ -13,35 +13,6 @@
#include "render/pixel_format.h" #include "render/pixel_format.h"
#include "render/wlr_renderer.h" #include "render/wlr_renderer.h"
bool init_drm_renderer(struct wlr_drm_backend *drm,
struct wlr_drm_renderer *renderer) {
renderer->wlr_rend = renderer_autocreate_with_drm_fd(drm->fd);
if (!renderer->wlr_rend) {
wlr_log(WLR_ERROR, "Failed to create renderer");
return false;
}
uint32_t backend_caps = backend_get_buffer_caps(&drm->backend);
renderer->allocator = allocator_autocreate_with_drm_fd(backend_caps,
renderer->wlr_rend, drm->fd);
if (renderer->allocator == NULL) {
wlr_log(WLR_ERROR, "Failed to create allocator");
wlr_renderer_destroy(renderer->wlr_rend);
return false;
}
return true;
}
void finish_drm_renderer(struct wlr_drm_renderer *renderer) {
if (!renderer) {
return;
}
wlr_allocator_destroy(renderer->allocator);
wlr_renderer_destroy(renderer->wlr_rend);
}
void finish_drm_surface(struct wlr_drm_surface *surf) { void finish_drm_surface(struct wlr_drm_surface *surf) {
if (!surf || !surf->renderer) { if (!surf || !surf->renderer) {
return; return;
@ -85,62 +56,6 @@ bool init_drm_surface(struct wlr_drm_surface *surf,
return true; return true;
} }
struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
struct wlr_buffer *buffer,
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point) {
struct wlr_renderer *renderer = surf->renderer->wlr_rend;
if (surf->swapchain->width != buffer->width ||
surf->swapchain->height != buffer->height) {
wlr_log(WLR_ERROR, "Surface size doesn't match buffer size");
return NULL;
}
struct wlr_texture *tex = wlr_texture_from_buffer(renderer, buffer);
if (tex == NULL) {
wlr_log(WLR_ERROR, "Failed to import source buffer into multi-GPU renderer");
return NULL;
}
struct wlr_buffer *dst = wlr_swapchain_acquire(surf->swapchain);
if (!dst) {
wlr_log(WLR_ERROR, "Failed to acquire multi-GPU swapchain buffer");
goto error_tex;
}
surf->point++;
const struct wlr_buffer_pass_options pass_options = {
.signal_timeline = surf->timeline,
.signal_point = surf->point,
};
struct wlr_render_pass *pass = wlr_renderer_begin_buffer_pass(renderer, dst, &pass_options);
if (pass == NULL) {
wlr_log(WLR_ERROR, "Failed to begin render pass with multi-GPU destination buffer");
goto error_dst;
}
wlr_render_pass_add_texture(pass, &(struct wlr_render_texture_options){
.texture = tex,
.blend_mode = WLR_RENDER_BLEND_MODE_NONE,
.wait_timeline = wait_timeline,
.wait_point = wait_point,
});
if (!wlr_render_pass_submit(pass)) {
wlr_log(WLR_ERROR, "Failed to submit multi-GPU render pass");
goto error_dst;
}
wlr_texture_destroy(tex);
return dst;
error_dst:
wlr_buffer_unlock(dst);
error_tex:
wlr_texture_destroy(tex);
return NULL;
}
bool drm_plane_pick_render_format(struct wlr_drm_plane *plane, bool drm_plane_pick_render_format(struct wlr_drm_plane *plane,
struct wlr_drm_format *fmt, struct wlr_drm_renderer *renderer) { struct wlr_drm_format *fmt, struct wlr_drm_renderer *renderer) {
const struct wlr_drm_format_set *render_formats = const struct wlr_drm_format_set *render_formats =

View file

@ -19,9 +19,6 @@ struct wlr_drm_plane {
uint32_t type; uint32_t type;
uint32_t id; uint32_t id;
/* Only initialized on multi-GPU setups */
struct wlr_drm_surface mgpu_surf;
/* Buffer submitted to the kernel, will be presented on next vblank */ /* Buffer submitted to the kernel, will be presented on next vblank */
struct wlr_drm_fb *queued_fb; struct wlr_drm_fb *queued_fb;
/* Buffer currently displayed on screen */ /* Buffer currently displayed on screen */
@ -80,7 +77,6 @@ struct wlr_drm_crtc {
struct wlr_drm_backend { struct wlr_drm_backend {
struct wlr_backend backend; struct wlr_backend backend;
struct wlr_drm_backend *parent;
const struct wlr_drm_interface *iface; const struct wlr_drm_interface *iface;
bool addfb2_modifiers; bool addfb2_modifiers;
@ -99,7 +95,6 @@ struct wlr_drm_backend {
struct wl_listener session_destroy; struct wl_listener session_destroy;
struct wl_listener session_active; struct wl_listener session_active;
struct wl_listener parent_destroy;
struct wl_listener dev_change; struct wl_listener dev_change;
struct wl_listener dev_remove; struct wl_listener dev_remove;
@ -108,15 +103,10 @@ struct wlr_drm_backend {
struct wl_list page_flips; // wlr_drm_page_flip.link struct wl_list page_flips; // wlr_drm_page_flip.link
/* Only initialized on multi-GPU setups */
struct wlr_drm_renderer mgpu_renderer;
struct wlr_session *session; struct wlr_session *session;
uint64_t cursor_width, cursor_height; uint64_t cursor_width, cursor_height;
struct wlr_drm_format_set mgpu_formats;
bool supports_tearing_page_flips; bool supports_tearing_page_flips;
}; };

View file

@ -25,19 +25,11 @@ struct wlr_drm_surface {
uint64_t point; uint64_t point;
}; };
bool init_drm_renderer(struct wlr_drm_backend *drm,
struct wlr_drm_renderer *renderer);
void finish_drm_renderer(struct wlr_drm_renderer *renderer);
bool init_drm_surface(struct wlr_drm_surface *surf, bool init_drm_surface(struct wlr_drm_surface *surf,
struct wlr_drm_renderer *renderer, int width, int height, struct wlr_drm_renderer *renderer, int width, int height,
const struct wlr_drm_format *drm_format); const struct wlr_drm_format *drm_format);
void finish_drm_surface(struct wlr_drm_surface *surf); void finish_drm_surface(struct wlr_drm_surface *surf);
struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
struct wlr_buffer *buffer,
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point);
bool drm_plane_pick_render_format(struct wlr_drm_plane *plane, bool drm_plane_pick_render_format(struct wlr_drm_plane *plane,
struct wlr_drm_format *fmt, struct wlr_drm_renderer *renderer); struct wlr_drm_format *fmt, struct wlr_drm_renderer *renderer);

View file

@ -32,21 +32,12 @@ struct wlr_drm_lease {
/** /**
* Creates a DRM backend using the specified GPU file descriptor (typically from * Creates a DRM backend using the specified GPU file descriptor (typically from
* a device node in /dev/dri). * a device node in /dev/dri).
*
* To slave this to another DRM backend, pass it as the parent (which _must_ be
* a DRM backend, other kinds of backends raise SIGABRT).
*/ */
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session, struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session, struct wlr_device *dev);
struct wlr_device *dev, struct wlr_backend *parent);
bool wlr_backend_is_drm(struct wlr_backend *backend); bool wlr_backend_is_drm(struct wlr_backend *backend);
bool wlr_output_is_drm(struct wlr_output *output); bool wlr_output_is_drm(struct wlr_output *output);
/**
* Get the parent DRM backend, if any.
*/
struct wlr_backend *wlr_drm_backend_get_parent(struct wlr_backend *backend);
/** /**
* Get the KMS connector object ID. * Get the KMS connector object ID.
*/ */

View file

@ -1068,15 +1068,6 @@ static bool devid_from_fd(int fd, dev_t *devid) {
return true; return true;
} }
static bool is_secondary_drm_backend(struct wlr_backend *backend) {
#if WLR_HAS_DRM_BACKEND
return wlr_backend_is_drm(backend) &&
wlr_drm_backend_get_parent(backend) != NULL;
#else
return false;
#endif
}
bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feedback_v1 *feedback, bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feedback_v1 *feedback,
const struct wlr_linux_dmabuf_feedback_v1_init_options *options) { const struct wlr_linux_dmabuf_feedback_v1_init_options *options) {
assert(options->main_renderer != NULL); assert(options->main_renderer != NULL);
@ -1119,8 +1110,7 @@ bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feed
wlr_log(WLR_ERROR, "Failed to intersect renderer and scanout formats"); wlr_log(WLR_ERROR, "Failed to intersect renderer and scanout formats");
goto error; goto error;
} }
} else if (options->scanout_primary_output != NULL && } else if (options->scanout_primary_output != NULL) {
!is_secondary_drm_backend(options->scanout_primary_output->backend)) {
int backend_drm_fd = wlr_backend_get_drm_fd(options->scanout_primary_output->backend); int backend_drm_fd = wlr_backend_get_drm_fd(options->scanout_primary_output->backend);
if (backend_drm_fd < 0) { if (backend_drm_fd < 0) {
wlr_log(WLR_ERROR, "Failed to get backend DRM FD"); wlr_log(WLR_ERROR, "Failed to get backend DRM FD");