[mesa3d] Sync all patch files with DDK 1.17.
This commit is contained in:
@@ -0,0 +1,433 @@
|
||||
From db015d5fd0ded075e759677c047c581151bb1b52 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Tue, 9 Mar 2021 17:15:30 +0000
|
||||
Subject: [PATCH 50/67] dri: preserve the original FD for driver use.
|
||||
|
||||
If an application uses a different GPU from the default, allow the
|
||||
file descriptor (FD) for that original GPU/display to be preserved
|
||||
for use by drivers. Drivers may wish to use the original FD to
|
||||
allocate shared surfaces, to ensure the surface properties are
|
||||
compatible with the original GPU/display (e.g. for X11 or Wayland).
|
||||
|
||||
This feature is only available on platforms that choose to support
|
||||
it, by implementing the new getDisplayFD function in the DRI image,
|
||||
and DRI2 loader extensions.
|
||||
|
||||
If the feature is available, drivers can obtain the original FD
|
||||
by calling the getDisplayFD function in the relevant loader extension.
|
||||
Drivers should check the FD is valid before use (i.e. not -1). If
|
||||
the FD is valid, it may be equal to the current GPU FD if a different
|
||||
GPU is not being used. The FD is owned by the platform, not the
|
||||
driver, and the platform is responsible for closing it.
|
||||
|
||||
The feature is currently supported by the Wayland, and DRI3 based
|
||||
X11 EGL and GLX platforms.
|
||||
---
|
||||
include/GL/internal/dri_interface.h | 26 +++++++++++++++++--
|
||||
src/egl/drivers/dri2/egl_dri2.c | 10 +++++++
|
||||
src/egl/drivers/dri2/egl_dri2.h | 1 +
|
||||
src/egl/drivers/dri2/platform_wayland.c | 31 ++++++++++++++++++++--
|
||||
src/egl/drivers/dri2/platform_x11.c | 3 +++
|
||||
src/egl/drivers/dri2/platform_x11_dri3.c | 27 ++++++++++++++++++-
|
||||
src/glx/dri3_glx.c | 33 ++++++++++++++++++++++--
|
||||
src/glx/dri3_priv.h | 1 +
|
||||
8 files changed, 125 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
|
||||
index 888a117d56e..2fb440feb50 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1146,7 +1146,7 @@ struct __DRIbufferRec {
|
||||
};
|
||||
|
||||
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
|
||||
-#define __DRI_DRI2_LOADER_VERSION 5
|
||||
+#define __DRI_DRI2_LOADER_VERSION 6
|
||||
|
||||
enum dri_loader_cap {
|
||||
/* Whether the loader handles RGBA channel ordering correctly. If not,
|
||||
@@ -1227,6 +1227,17 @@ struct __DRIdri2LoaderExtensionRec {
|
||||
* \since 5
|
||||
*/
|
||||
void (*destroyLoaderImageState)(void *loaderPrivate);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the display FD
|
||||
+ *
|
||||
+ * Get the FD of the display device.
|
||||
+ *
|
||||
+ * \param loaderPrivate The last parameter of createNewScreen or
|
||||
+ * createNewScreen2.
|
||||
+ * \since 6
|
||||
+ */
|
||||
+ int (*getDisplayFD)(void *loaderPrivate);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2131,7 +2142,7 @@ struct __DRIimageList {
|
||||
};
|
||||
|
||||
#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
|
||||
-#define __DRI_IMAGE_LOADER_VERSION 4
|
||||
+#define __DRI_IMAGE_LOADER_VERSION 5
|
||||
|
||||
struct __DRIimageLoaderExtensionRec {
|
||||
__DRIextension base;
|
||||
@@ -2199,6 +2210,17 @@ struct __DRIimageLoaderExtensionRec {
|
||||
* \since 4
|
||||
*/
|
||||
void (*destroyLoaderImageState)(void *loaderPrivate);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the display FD
|
||||
+ *
|
||||
+ * Get the FD of the display device.
|
||||
+ *
|
||||
+ * \param loaderPrivate The last parameter of createNewScreen or
|
||||
+ * createNewScreen2.
|
||||
+ * \since 5
|
||||
+ */
|
||||
+ int (*getDisplayFD)(void *loaderPrivate);
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
|
||||
index c4a49cae592..1df53ef011c 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -1367,6 +1367,16 @@ dri2_display_destroy(_EGLDisplay *disp)
|
||||
break;
|
||||
}
|
||||
|
||||
+ switch (disp->Platform) {
|
||||
+ case _EGL_PLATFORM_WAYLAND:
|
||||
+ case _EGL_PLATFORM_X11:
|
||||
+ if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
if (dri2_dpy->fd >= 0)
|
||||
close(dri2_dpy->fd);
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
|
||||
index 141df1b1732..af03caee623 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -230,6 +230,7 @@ struct dri2_egl_display
|
||||
const __DRIconfigOptionsExtension *configOptions;
|
||||
const __DRImutableRenderBufferDriverExtension *mutable_render_buffer;
|
||||
int fd;
|
||||
+ int fd_dpy;
|
||||
|
||||
/* dri2_initialize/dri2_terminate increment/decrement this count, so does
|
||||
* dri2_make_current (tracks if there are active contexts/surfaces). */
|
||||
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
|
||||
index 06272d4081e..b393e058770 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "loader.h"
|
||||
#include "util/u_vector.h"
|
||||
#include "util/anon_file.h"
|
||||
+#include "util/os_file.h"
|
||||
#include "eglglobals.h"
|
||||
|
||||
#include <wayland-egl-backend.h>
|
||||
@@ -973,21 +974,32 @@ dri2_wl_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri2_wl_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ _EGLDisplay *disp = loaderPrivate;
|
||||
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
+
|
||||
+ return dri2_dpy->fd_dpy;
|
||||
+}
|
||||
+
|
||||
static const __DRIdri2LoaderExtension dri2_loader_extension = {
|
||||
- .base = { __DRI_DRI2_LOADER, 4 },
|
||||
+ .base = { __DRI_DRI2_LOADER, 6 },
|
||||
|
||||
.getBuffers = dri2_wl_get_buffers,
|
||||
.flushFrontBuffer = dri2_wl_flush_front_buffer,
|
||||
.getBuffersWithFormat = dri2_wl_get_buffers_with_format,
|
||||
.getCapability = dri2_wl_get_capability,
|
||||
+ .getDisplayFD = dri2_wl_get_display_fd,
|
||||
};
|
||||
|
||||
static const __DRIimageLoaderExtension image_loader_extension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 2 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = image_get_buffers,
|
||||
.flushFrontBuffer = dri2_wl_flush_front_buffer,
|
||||
.getCapability = dri2_wl_get_capability,
|
||||
+ .getDisplayFD = dri2_wl_get_display_fd,
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1640,12 +1652,14 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
|
||||
{
|
||||
_EGLDevice *dev;
|
||||
struct dri2_egl_display *dri2_dpy;
|
||||
+ int fd_old;
|
||||
|
||||
dri2_dpy = calloc(1, sizeof *dri2_dpy);
|
||||
if (!dri2_dpy)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
disp->DriverData = (void *) dri2_dpy;
|
||||
if (disp->PlatformDisplay == NULL) {
|
||||
dri2_dpy->wl_dpy = wl_display_connect(NULL);
|
||||
@@ -1690,8 +1704,20 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
|
||||
(roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated))
|
||||
goto cleanup;
|
||||
|
||||
+ fd_old = dri2_dpy->fd;
|
||||
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
|
||||
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
|
||||
&dri2_dpy->is_different_gpu);
|
||||
+ if (dri2_dpy->fd == fd_old) {
|
||||
+ if (dri2_dpy->fd_dpy != -1)
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
+
|
||||
+ dri2_dpy->fd_dpy = dri2_dpy->fd;
|
||||
+ } else if (dri2_dpy->fd_dpy == -1) {
|
||||
+ _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to dup display FD");
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
dev = _eglAddDevice(dri2_dpy->fd, false);
|
||||
if (!dev) {
|
||||
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
|
||||
@@ -2236,6 +2262,7 @@ dri2_initialize_wayland_swrast(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
disp->DriverData = (void *) dri2_dpy;
|
||||
if (disp->PlatformDisplay == NULL) {
|
||||
dri2_dpy->wl_dpy = wl_display_connect(NULL);
|
||||
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
|
||||
index 5ffdf132184..5cf3ce2a369 100644
|
||||
--- a/src/egl/drivers/dri2/platform_x11.c
|
||||
+++ b/src/egl/drivers/dri2/platform_x11.c
|
||||
@@ -1277,6 +1277,7 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
if (!dri2_get_xcb_connection(disp, dri2_dpy))
|
||||
goto cleanup;
|
||||
|
||||
@@ -1364,6 +1365,7 @@ dri2_initialize_x11_dri3(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
if (!dri2_get_xcb_connection(disp, dri2_dpy))
|
||||
goto cleanup;
|
||||
|
||||
@@ -1472,6 +1474,7 @@ dri2_initialize_x11_dri2(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
if (!dri2_get_xcb_connection(disp, dri2_dpy))
|
||||
goto cleanup;
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
index e117105fcb6..0babf9f867e 100644
|
||||
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include "util/macros.h"
|
||||
+#include "util/os_file.h"
|
||||
|
||||
#include "egl_dri2.h"
|
||||
#include "platform_x11_dri3.h"
|
||||
@@ -414,11 +415,21 @@ dri3_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
|
||||
_eglLog(_EGL_WARNING, "FIXME: egl/x11 doesn't support front buffer rendering.");
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri3_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ _EGLDisplay *disp = loaderPrivate;
|
||||
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
+
|
||||
+ return dri2_dpy->fd_dpy;
|
||||
+}
|
||||
+
|
||||
const __DRIimageLoaderExtension dri3_image_loader_extension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 1 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = loader_dri3_get_buffers,
|
||||
.flushFrontBuffer = dri3_flush_front_buffer,
|
||||
+ .getDisplayFD = dri3_get_display_fd,
|
||||
};
|
||||
|
||||
static EGLBoolean
|
||||
@@ -537,6 +548,7 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
|
||||
xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
|
||||
xcb_generic_error_t *error;
|
||||
const xcb_query_extension_reply_t *extension;
|
||||
+ int fd_old;
|
||||
|
||||
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id);
|
||||
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_present_id);
|
||||
@@ -616,12 +628,25 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
+ fd_old = dri2_dpy->fd;
|
||||
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
|
||||
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, &dri2_dpy->is_different_gpu);
|
||||
+ if (dri2_dpy->fd == fd_old) {
|
||||
+ if (dri2_dpy->fd_dpy != -1)
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
+
|
||||
+ dri2_dpy->fd_dpy = dri2_dpy->fd;
|
||||
+ } else if (dri2_dpy->fd_dpy == -1) {
|
||||
+ _eglLog(_EGL_WARNING, "DRI3: failed to dup display FD");
|
||||
+ close(dri2_dpy->fd);
|
||||
+ return EGL_FALSE;
|
||||
+ }
|
||||
|
||||
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
|
||||
if (!dri2_dpy->driver_name) {
|
||||
_eglLog(_EGL_WARNING, "DRI3: No driver found");
|
||||
close(dri2_dpy->fd);
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
|
||||
index db1b079663f..1ed6b60ffe8 100644
|
||||
--- a/src/glx/dri3_glx.c
|
||||
+++ b/src/glx/dri3_glx.c
|
||||
@@ -77,6 +77,7 @@
|
||||
#include "dri3_priv.h"
|
||||
#include "loader.h"
|
||||
#include "dri2.h"
|
||||
+#include "util/os_file.h"
|
||||
|
||||
static struct dri3_drawable *
|
||||
loader_drawable_to_dri3_drawable(struct loader_dri3_drawable *draw) {
|
||||
@@ -529,6 +530,14 @@ dri3_flush_swap_buffers(__DRIdrawable *driDrawable, void *loaderPrivate)
|
||||
loader_dri3_swapbuffer_barrier(draw);
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri3_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ struct dri3_screen *psc = (struct dri3_screen *)loaderPrivate;
|
||||
+
|
||||
+ return psc->fd_dpy;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dri_set_background_context(void *loaderPrivate)
|
||||
{
|
||||
@@ -548,11 +557,12 @@ dri_is_thread_safe(void *loaderPrivate)
|
||||
/* The image loader extension record for DRI3
|
||||
*/
|
||||
static const __DRIimageLoaderExtension imageLoaderExtension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 3 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = loader_dri3_get_buffers,
|
||||
.flushFrontBuffer = dri3_flush_front_buffer,
|
||||
.flushSwapBuffers = dri3_flush_swap_buffers,
|
||||
+ .getDisplayFD = dri3_get_display_fd,
|
||||
};
|
||||
|
||||
const __DRIuseInvalidateExtension dri3UseInvalidate = {
|
||||
@@ -618,6 +628,10 @@ dri3_destroy_screen(struct glx_screen *base)
|
||||
loader_dri3_close_screen(psc->driScreen);
|
||||
(*psc->core->destroyScreen) (psc->driScreen);
|
||||
driDestroyConfigs(psc->driver_configs);
|
||||
+
|
||||
+ if (psc->fd_dpy != psc->fd)
|
||||
+ close(psc->fd_dpy);
|
||||
+
|
||||
close(psc->fd);
|
||||
free(psc);
|
||||
}
|
||||
@@ -842,8 +856,9 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
struct dri3_screen *psc;
|
||||
__GLXDRIscreen *psp;
|
||||
struct glx_config *configs = NULL, *visuals = NULL;
|
||||
- char *driverName, *driverNameDisplayGPU, *tmp;
|
||||
+ char *driverName = NULL, *driverNameDisplayGPU, *tmp;
|
||||
int i;
|
||||
+ int fd_old;
|
||||
|
||||
psc = calloc(1, sizeof *psc);
|
||||
if (psc == NULL)
|
||||
@@ -851,6 +866,7 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
|
||||
psc->fd = -1;
|
||||
psc->fd_display_gpu = -1;
|
||||
+ psc->fd_dpy = -1;
|
||||
|
||||
if (!glx_screen_init(&psc->base, screen, priv)) {
|
||||
free(psc);
|
||||
@@ -871,12 +887,23 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ fd_old = psc->fd;
|
||||
+ psc->fd_dpy = os_dupfd_cloexec(psc->fd);
|
||||
psc->fd_display_gpu = fcntl(psc->fd, F_DUPFD_CLOEXEC, 3);
|
||||
psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu);
|
||||
if (!psc->is_different_gpu) {
|
||||
close(psc->fd_display_gpu);
|
||||
psc->fd_display_gpu = -1;
|
||||
}
|
||||
+ if (psc->fd == fd_old) {
|
||||
+ if (psc->fd_dpy != -1)
|
||||
+ close(psc->fd_dpy);
|
||||
+
|
||||
+ psc->fd_dpy = psc->fd;
|
||||
+ } else if (psc->fd_dpy == -1) {
|
||||
+ ErrorMessageF("Unable to dup the display FD");
|
||||
+ goto handle_error;
|
||||
+ }
|
||||
|
||||
driverName = loader_get_driver_for_fd(psc->fd);
|
||||
if (!driverName) {
|
||||
@@ -1049,6 +1076,8 @@ handle_error:
|
||||
if (psc->driScreenDisplayGPU)
|
||||
psc->core->destroyScreen(psc->driScreenDisplayGPU);
|
||||
psc->driScreenDisplayGPU = NULL;
|
||||
+ if (psc->fd_dpy >= 0 && psc->fd_dpy != psc->fd)
|
||||
+ close(psc->fd_dpy);
|
||||
if (psc->fd >= 0)
|
||||
close(psc->fd);
|
||||
if (psc->fd_display_gpu >= 0)
|
||||
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
|
||||
index c0e833c16ef..b3dccf28c06 100644
|
||||
--- a/src/glx/dri3_priv.h
|
||||
+++ b/src/glx/dri3_priv.h
|
||||
@@ -107,6 +107,7 @@ struct dri3_screen {
|
||||
|
||||
void *driver;
|
||||
int fd;
|
||||
+ int fd_dpy;
|
||||
bool is_different_gpu;
|
||||
|
||||
/* fd for display GPU in case of prime */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Reference in New Issue
Block a user