123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- From f92304242d7656cf296e978eb9e4a5fc09050b75 Mon Sep 17 00:00:00 2001
- From: Brendan King <Brendan.King@imgtec.com>
- Date: Thu, 20 May 2021 14:43:29 +0100
- Subject: [PATCH] egl/drm: add support for DRI_PRIME GPU selection
- Add support for selecting the GPU to be used for rendering using
- the DRI_PRIME environment variable. If a different GPU is selected,
- a duplicate of the file descriptor for the original GPU/display is
- preserved, which can be obtained by calling the getDisplayFD
- function in the image loader extension.
- For server side Wayland, the ability to support PRIME is
- determined by checking for the PRIME import and export
- capabilities on the driver file descriptor, which may no
- longer support them if a different GPU from the default has
- been selected. It may be that the driver can still support
- PRIME; for example, by making use of the original (default)
- file descriptor. The driver can indicate it supports PRIME
- via the getCapabilities function in the DRI Image extension.
- ---
- include/GL/internal/dri_interface.h | 2 ++
- src/egl/drivers/dri2/egl_dri2.c | 10 ++++++++
- src/egl/drivers/dri2/platform_drm.c | 19 ++++++++++-----
- src/gbm/backends/dri/gbm_dri.c | 38 +++++++++++++++++++++++++----
- src/gbm/backends/dri/gbm_driint.h | 8 ++++++
- 5 files changed, 66 insertions(+), 11 deletions(-)
- diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
- index 2fb440f..080d191 100644
- --- a/include/GL/internal/dri_interface.h
- +++ b/include/GL/internal/dri_interface.h
- @@ -1548,6 +1548,8 @@ enum __DRIChromaSiting {
- */
- /*@{*/
- #define __DRI_IMAGE_CAP_GLOBAL_NAMES 1
- +#define __DRI_IMAGE_CAP_PRIME_IMPORT 0x2000
- +#define __DRI_IMAGE_CAP_PRIME_EXPORT 0x4000
- /*@}*/
-
- /**
- diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
- index 1df53ef..ec4ac60 100644
- --- a/src/egl/drivers/dri2/egl_dri2.c
- +++ b/src/egl/drivers/dri2/egl_dri2.c
- @@ -1368,6 +1368,7 @@ dri2_display_destroy(_EGLDisplay *disp)
- }
-
- switch (disp->Platform) {
- + case _EGL_PLATFORM_DRM:
- case _EGL_PLATFORM_WAYLAND:
- case _EGL_PLATFORM_X11:
- if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
- @@ -3943,6 +3944,15 @@ dri2_bind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy)
- dri2_dpy->image->base.version >= 7 &&
- dri2_dpy->image->createImageFromFds != NULL)
- flags |= WAYLAND_DRM_PRIME;
- + else if (dri2_dpy->image->base.version >= 10 &&
- + dri2_dpy->image->getCapabilities != NULL) {
- + int capabilities;
- +
- + capabilities = dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
- + if ((capabilities & __DRI_IMAGE_CAP_PRIME_IMPORT) != 0 &&
- + (capabilities & __DRI_IMAGE_CAP_PRIME_EXPORT) != 0)
- + flags |= WAYLAND_DRM_PRIME;
- + }
-
- dri2_dpy->wl_server_drm =
- wayland_drm_init(wl_dpy, device_name,
- diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
- index 258e8b6..f160ad1 100644
- --- a/src/egl/drivers/dri2/platform_drm.c
- +++ b/src/egl/drivers/dri2/platform_drm.c
- @@ -595,7 +595,7 @@ dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
- {
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-
- - return drmAuthMagic(dri2_dpy->fd, id);
- + return drmAuthMagic(dri2_dpy->fd_dpy, id);
- }
-
- static void
- @@ -782,6 +782,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
- return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
- dri2_dpy->fd = -1;
- + dri2_dpy->fd_dpy = -1;
- disp->DriverData = (void *) dri2_dpy;
-
- gbm = disp->PlatformDisplay;
- @@ -789,16 +790,16 @@ dri2_initialize_drm(_EGLDisplay *disp)
- 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 = loader_open_device(buf);
- - gbm = gbm_create_device(dri2_dpy->fd);
- + dri2_dpy->fd_dpy = loader_open_device(buf);
- + gbm = gbm_create_device(dri2_dpy->fd_dpy);
- if (gbm == NULL) {
- err = "DRI2: failed to create gbm device";
- goto cleanup;
- }
- dri2_dpy->own_device = true;
- } else {
- - dri2_dpy->fd = os_dupfd_cloexec(gbm_device_get_fd(gbm));
- - if (dri2_dpy->fd < 0) {
- + dri2_dpy->fd_dpy = os_dupfd_cloexec(gbm_device_get_fd(gbm));
- + if (dri2_dpy->fd_dpy < 0) {
- err = "DRI2: failed to fcntl() existing gbm device";
- goto cleanup;
- }
- @@ -810,6 +811,12 @@ dri2_initialize_drm(_EGLDisplay *disp)
- goto cleanup;
- }
-
- + if (gbm_dri_device_get_fd(dri2_dpy->gbm_dri) ==
- + gbm_device_get_fd(gbm))
- + dri2_dpy->fd = dri2_dpy->fd_dpy;
- + else
- + dri2_dpy->fd = os_dupfd_cloexec(gbm_dri_device_get_fd(dri2_dpy->gbm_dri));
- +
- dev = _eglAddDevice(dri2_dpy->fd, dri2_dpy->gbm_dri->software);
- if (!dev) {
- err = "DRI2: failed to find EGLDevice";
- @@ -872,7 +879,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
- disp->Extensions.EXT_buffer_age = EGL_TRUE;
-
- #ifdef HAVE_WAYLAND_PLATFORM
- - dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
- + dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd_dpy);
- #endif
- dri2_set_WL_bind_wayland_display(disp);
-
- diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
- index 5acb15b..c1586f4 100644
- --- a/src/gbm/backends/dri/gbm_dri.c
- +++ b/src/gbm/backends/dri/gbm_dri.c
- @@ -51,6 +51,7 @@
- #include "loader.h"
- #include "util/debug.h"
- #include "util/macros.h"
- +#include "util/os_file.h"
-
- /* For importing wl_buffer */
- #if HAVE_WAYLAND_PLATFORM
- @@ -141,6 +142,14 @@ image_get_buffers(__DRIdrawable *driDrawable,
- surf->dri_private, buffer_mask, buffers);
- }
-
- +static int
- +dri_get_display_fd(void *loaderPrivate)
- +{
- + struct gbm_dri_device *dri = loaderPrivate;
- +
- + return dri->base.v0.fd;
- +}
- +
- static void
- swrast_get_drawable_info(__DRIdrawable *driDrawable,
- int *x,
- @@ -220,20 +229,22 @@ static const __DRIimageLookupExtension image_lookup_extension = {
- };
-
- static const __DRIdri2LoaderExtension dri2_loader_extension = {
- - .base = { __DRI_DRI2_LOADER, 4 },
- + .base = { __DRI_DRI2_LOADER, 6 },
-
- .getBuffers = dri_get_buffers,
- .flushFrontBuffer = dri_flush_front_buffer,
- .getBuffersWithFormat = dri_get_buffers_with_format,
- .getCapability = dri_get_capability,
- + .getDisplayFD = dri_get_display_fd,
- };
-
- static const __DRIimageLoaderExtension image_loader_extension = {
- - .base = { __DRI_IMAGE_LOADER, 2 },
- + .base = { __DRI_IMAGE_LOADER, 5 },
-
- .getBuffers = image_get_buffers,
- .flushFrontBuffer = dri_flush_front_buffer,
- .getCapability = dri_get_capability,
- + .getDisplayFD = dri_get_display_fd,
- };
-
- static const __DRIswrastLoaderExtension swrast_loader_extension = {
- @@ -398,12 +409,12 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name)
- return -1;
-
- if (dri->dri2->base.version >= 4) {
- - dri->screen = dri->dri2->createNewScreen2(0, dri->base.v0.fd,
- + dri->screen = dri->dri2->createNewScreen2(0, dri->fd,
- dri->loader_extensions,
- dri->driver_extensions,
- &dri->driver_configs, dri);
- } else {
- - dri->screen = dri->dri2->createNewScreen(0, dri->base.v0.fd,
- + dri->screen = dri->dri2->createNewScreen(0, dri->fd,
- dri->loader_extensions,
- &dri->driver_configs, dri);
- }
- @@ -470,8 +481,20 @@ static int
- dri_screen_create(struct gbm_dri_device *dri)
- {
- char *driver_name;
- + int dup_fd, new_fd;
- + bool is_different_gpu;
-
- - driver_name = loader_get_driver_for_fd(dri->base.v0.fd);
- + dup_fd = os_dupfd_cloexec(dri->fd);
- + if (dup_fd < 0)
- + return -1;
- +
- + new_fd = loader_get_user_preferred_fd(dup_fd, &is_different_gpu);
- + if (new_fd == dup_fd)
- + close(new_fd);
- + else
- + dri->fd = new_fd;
- +
- + driver_name = loader_get_driver_for_fd(dri->fd);
- if (!driver_name)
- return -1;
-
- @@ -1424,6 +1447,9 @@ dri_destroy(struct gbm_device *gbm)
- dlclose(dri->driver);
- free(dri->driver_name);
-
- + if (dri->fd >= 0 && dri->fd != dri->base.v0.fd)
- + close (dri->fd);
- +
- free(dri);
- }
-
- @@ -1445,6 +1471,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
- if (!dri)
- return NULL;
-
- + dri->fd = fd;
- +
- dri->base.v0.fd = fd;
- dri->base.v0.backend_version = gbm_backend_version;
- dri->base.v0.bo_create = gbm_dri_bo_create;
- diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
- index 9e77ba5..e33a96e 100644
- --- a/src/gbm/backends/dri/gbm_driint.h
- +++ b/src/gbm/backends/dri/gbm_driint.h
- @@ -61,6 +61,8 @@ struct gbm_dri_visual {
- struct gbm_dri_device {
- struct gbm_device base;
-
- + int fd;
- +
- void *driver;
- char *driver_name; /* Name of the DRI module, without the _dri suffix */
- bool software; /* A software driver was loaded */
- @@ -191,4 +193,10 @@ gbm_dri_bo_unmap_dumb(struct gbm_dri_bo *bo)
- bo->map = NULL;
- }
-
- +static inline int
- +gbm_dri_device_get_fd(struct gbm_dri_device *dri)
- +{
- + return dri->fd;
- +}
- +
- #endif
|