From 88c03ddd345fe6b0cd16c11cb5c5309f8d7d16ff Mon Sep 17 00:00:00 2001 From: Leandro Ribeiro Date: Mon, 4 Sep 2023 13:53:12 -0300 Subject: [PATCH] egl/drm: get compatible render-only device fd for kms-only device Things have been working by accident for split display/render SoCs when using the GBM platform. The device fd given to the GBM platform may be associated with a KMS-only device, so _eglFindDevice() should find nothing (because the global EGLDevice list only has render-capable devices). The only thing making it work is that we don't error out when we go through the EGLDevice list and can't find the device we are looking for. We simply return the last EGLDevice from the list. This patch fixes that. Now we look for a compatible render-only device for the KMS-only in the GBM platform. Signed-off-by: Leandro Ribeiro Reviewed-by: Simon Ser Reviewed-by: Daniel Stone Part-of: --- src/egl/drivers/dri2/platform_drm.c | 33 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 7b56a9a37ab..37623f7d7b3 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -562,6 +562,20 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = { .get_dri_drawable = dri2_surface_get_dri_drawable, }; +static int +get_fd_render_gpu_drm(struct gbm_dri_device *gbm_dri, int fd_display_gpu) +{ + /* This doesn't make sense for the software case. */ + assert(!gbm_dri->software); + + /* Render-capable device, so just return the same fd. */ + if (loader_is_device_render_capable(fd_display_gpu)) + return fd_display_gpu; + + /* Display-only device, so return a compatible render-only device. */ + return gbm_dri->mesa->queryCompatibleRenderOnlyDeviceFd(fd_display_gpu); +} + EGLBoolean dri2_initialize_drm(_EGLDisplay *disp) { @@ -593,30 +607,37 @@ dri2_initialize_drm(_EGLDisplay *disp) goto cleanup; } - dri2_dpy->fd_render_gpu = + dri2_dpy->fd_display_gpu = loader_open_device(drm->nodes[DRM_NODE_PRIMARY]); } else { char buf[64]; int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0); if (n != -1 && n < sizeof(buf)) - dri2_dpy->fd_render_gpu = loader_open_device(buf); + dri2_dpy->fd_display_gpu = loader_open_device(buf); } - gbm = gbm_create_device(dri2_dpy->fd_render_gpu); + gbm = gbm_create_device(dri2_dpy->fd_display_gpu); if (gbm == NULL) { err = "DRI2: failed to create gbm device"; goto cleanup; } dri2_dpy->own_device = true; } else { - dri2_dpy->fd_render_gpu = os_dupfd_cloexec(gbm_device_get_fd(gbm)); - if (dri2_dpy->fd_render_gpu < 0) { + dri2_dpy->fd_display_gpu = os_dupfd_cloexec(gbm_device_get_fd(gbm)); + if (dri2_dpy->fd_display_gpu < 0) { err = "DRI2: failed to fcntl() existing gbm device"; goto cleanup; } } - dri2_dpy->fd_display_gpu = dri2_dpy->fd_render_gpu; dri2_dpy->gbm_dri = gbm_dri_device(gbm); + if (!dri2_dpy->gbm_dri->software) { + dri2_dpy->fd_render_gpu = + get_fd_render_gpu_drm(dri2_dpy->gbm_dri, dri2_dpy->fd_display_gpu); + if (dri2_dpy->fd_render_gpu < 0) { + err = "DRI2: failed to get compatible render device"; + goto cleanup; + } + } if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) { err = "DRI2: gbm device using incorrect/incompatible backend";