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 <leandro.ribeiro@collabora.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24825>
This commit is contained in:
Leandro Ribeiro
2023-09-04 13:53:12 -03:00
committed by Marge Bot
parent e10d8cd5dd
commit 88c03ddd34

View File

@@ -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";