diff --git a/backend/drm/backend.c b/backend/drm/backend.c index cee3cfa5..c9ffdcbe 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -53,8 +53,13 @@ static void backend_destroy(struct wlr_backend *backend) { wl_list_remove(&drm->dev_change.link); wl_list_remove(&drm->dev_remove.link); + gbm_device_destroy(drm->gbm); + + if (drm->parent) { + finish_drm_renderer(&drm->mgpu_renderer); + } + finish_drm_resources(drm); - finish_drm_renderer(&drm->renderer); free(drm->name); wlr_session_close_file(drm->session, drm->dev); @@ -219,8 +224,9 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, goto error_event; } - if (!init_drm_renderer(drm, &drm->renderer)) { - wlr_log(WLR_ERROR, "Failed to initialize renderer"); + drm->gbm = gbm_create_device(drm->fd); + if (!drm->gbm) { + wlr_log(WLR_ERROR, "Failed to create GBM device"); goto error_event; } @@ -229,9 +235,14 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, drm->backend.renderer = wlr_backend_get_renderer(&drm->parent->backend); assert(drm->backend.renderer != NULL); + if (!init_drm_renderer(drm, &drm->mgpu_renderer)) { + wlr_log(WLR_ERROR, "Failed to initialize renderer"); + goto error_event; + } + // 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->renderer.wlr_rend; + struct wlr_renderer *renderer = drm->mgpu_renderer.wlr_rend; const struct wlr_drm_format_set *texture_formats = wlr_renderer_get_dmabuf_texture_formats(renderer); if (texture_formats == NULL) { diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 1218fa9d..998c2074 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -401,14 +401,14 @@ static bool drm_connector_set_pending_fb(struct wlr_drm_connector *conn, struct wlr_buffer *local_buf; if (drm->parent) { struct wlr_drm_format *format = - drm_plane_pick_render_format(plane, &drm->renderer); + drm_plane_pick_render_format(plane, &drm->mgpu_renderer); if (format == NULL) { 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->renderer, + bool ok = init_drm_surface(&plane->mgpu_surf, &drm->mgpu_renderer, state->buffer->width, state->buffer->height, format); free(format); if (!ok) { @@ -632,14 +632,14 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn, int height = mode.vdisplay; struct wlr_drm_format *format = - drm_plane_pick_render_format(plane, &drm->renderer); + drm_plane_pick_render_format(plane, &drm->mgpu_renderer); if (format == NULL) { 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->renderer, + bool ok = init_drm_surface(&plane->mgpu_surf, &drm->mgpu_renderer, width, height, format); free(format); if (!ok) { @@ -834,13 +834,13 @@ static bool drm_connector_set_cursor(struct wlr_output *output, struct wlr_buffer *local_buf; if (drm->parent) { struct wlr_drm_format *format = - drm_plane_pick_render_format(plane, &drm->renderer); + drm_plane_pick_render_format(plane, &drm->mgpu_renderer); if (format == NULL) { wlr_log(WLR_ERROR, "Failed to pick cursor plane format"); return false; } - bool ok = init_drm_surface(&plane->mgpu_surf, &drm->renderer, + bool ok = init_drm_surface(&plane->mgpu_surf, &drm->mgpu_renderer, buffer->width, buffer->height, format); free(format); if (!ok) { diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 78a1d11f..7531ec32 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -23,32 +23,21 @@ bool init_drm_renderer(struct wlr_drm_backend *drm, struct wlr_drm_renderer *renderer) { renderer->backend = drm; - renderer->gbm = gbm_create_device(drm->fd); - if (!renderer->gbm) { - wlr_log(WLR_ERROR, "Failed to create GBM device"); - return false; - } - renderer->wlr_rend = renderer_autocreate_with_drm_fd(drm->fd); if (!renderer->wlr_rend) { wlr_log(WLR_ERROR, "Failed to create renderer"); - goto error_gbm; + return false; } renderer->allocator = allocator_autocreate_with_drm_fd(&drm->backend, renderer->wlr_rend, drm->fd); if (renderer->allocator == NULL) { wlr_log(WLR_ERROR, "Failed to create allocator"); - goto error_wlr_rend; + wlr_renderer_destroy(renderer->wlr_rend); + return false; } return true; - -error_wlr_rend: - wlr_renderer_destroy(renderer->wlr_rend); -error_gbm: - gbm_device_destroy(renderer->gbm); - return false; } void finish_drm_renderer(struct wlr_drm_renderer *renderer) { @@ -58,7 +47,6 @@ void finish_drm_renderer(struct wlr_drm_renderer *renderer) { wlr_allocator_destroy(renderer->allocator); wlr_renderer_destroy(renderer->wlr_rend); - gbm_device_destroy(renderer->gbm); } bool init_drm_surface(struct wlr_drm_surface *surf, @@ -287,7 +275,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm, } } - fb->bo = get_bo_for_dmabuf(drm->renderer.gbm, &attribs); + fb->bo = get_bo_for_dmabuf(drm->gbm, &attribs); if (!fb->bo) { wlr_log(WLR_DEBUG, "Failed to import DMA-BUF in GBM"); goto error_get_dmabuf; diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 881d4718..9aae5e0b 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -62,6 +62,7 @@ struct wlr_drm_backend { int fd; char *name; struct wlr_device *dev; + struct gbm_device *gbm; size_t num_crtcs; struct wlr_drm_crtc *crtcs; @@ -79,7 +80,9 @@ struct wlr_drm_backend { struct wl_list fbs; // wlr_drm_fb.link struct wl_list outputs; - struct wlr_drm_renderer renderer; + /* Only initialized on multi-GPU setups */ + struct wlr_drm_renderer mgpu_renderer; + struct wlr_session *session; uint64_t cursor_width, cursor_height; diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h index 528f2189..f6b996c7 100644 --- a/include/backend/drm/renderer.h +++ b/include/backend/drm/renderer.h @@ -13,7 +13,6 @@ struct wlr_buffer; struct wlr_drm_renderer { struct wlr_drm_backend *backend; - struct gbm_device *gbm; struct wlr_renderer *wlr_rend; struct wlr_allocator *allocator;