Files
fml13v01-buildroot/package/mesa3d/0045-egl-null-add-support-for-DRI_PRIME-GPU-selection.patch
T
Andy Hu 7566503cc1 package/{mesa3d, mesa3d-headers}: bump version to 22.1.3
upgrade the mesa3d and mesa3d-headers to v22.1.3
and copy patch from IMG DDK 1.19

keep the 0002-Force-Mesa-to-use-the-PVR-driver-for-platform-device.patch
to force the pvr driver

Note that the new version mesa3d support gallium driver
and no longer support dri driver

Signed-off-by: Andy Hu <andy.hu@starfivetech.com>
Signed-off-by: Windsome Zeng <Windsome.Zeng@starfivetech.com>
2023-06-01 22:08:04 +08:00

365 lines
13 KiB
Diff

From 42ecc1e6f730932fe4dcb9125652fe2e96aba1e9 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Thu, 20 May 2021 20:16:18 +0100
Subject: [PATCH 45/58] egl/null: 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.
This change includes code, in function dri2_null_try_device, to
optionally skip display devices that are not supported by a
particular DRI driver. This can be enabled by setting Meson build
option null-dri-driver-name. This feature is to prevent failure
on PC based test systems, that may have display and GPU hardware
other than that being tested.
---
meson.build | 4 +
meson_options.txt | 6 ++
src/egl/drivers/dri2/egl_dri2.c | 1 +
src/egl/drivers/dri2/platform_null.c | 135 +++++++++++++++++++--------
src/egl/meson.build | 5 +
5 files changed, 114 insertions(+), 37 deletions(-)
diff --git a/meson.build b/meson.build
index e021a896a0a..a37add42a6d 100644
--- a/meson.build
+++ b/meson.build
@@ -361,6 +361,10 @@ with_platform_haiku = _platforms.contains('haiku')
with_platform_windows = _platforms.contains('windows')
with_platform_null = _platforms.contains('null')
+if with_platform_null
+ null_dri_driver_name = get_option('null-dri-driver-name')
+endif
+
with_glx = get_option('glx')
if with_glx == 'auto'
if with_platform_android
diff --git a/meson_options.txt b/meson_options.txt
index 65f32547267..84661fb851f 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -37,6 +37,12 @@ option(
],
description : 'the window system EGL assumes for EGL_DEFAULT_DISPLAY',
)
+option(
+ 'null-dri-driver-name',
+ type : 'string',
+ value : '',
+ description : 'For the null platform, ignore all dri drivers apart from this one. By default, no dri drivers are ignored.'
+)
option(
'android-stub',
type : 'boolean',
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index d0503f614f6..fce277c6874 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1362,6 +1362,7 @@ dri2_display_destroy(_EGLDisplay *disp)
switch (disp->Platform) {
case _EGL_PLATFORM_DRM:
+ case _EGL_PLATFORM_NULL:
case _EGL_PLATFORM_WAYLAND:
case _EGL_PLATFORM_X11:
if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index c78e1fe0880..e2a138367f9 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -45,6 +45,7 @@
#include "egl_dri2.h"
#include "loader.h"
+#include "util/os_file.h"
#define NULL_CARD_MINOR_MAX 63U
@@ -1045,7 +1046,7 @@ swap_idle_get_target_frame(struct dri2_egl_surface *dri2_surf,
* current vblank by the number of intervals set at the time swapBuffer
* is called. For intervals of 1 or 0, we don't need a target frame.
*/
- err = display_get_vblank_sequence(dri2_dpy->fd, current_vblank_out);
+ err = display_get_vblank_sequence(dri2_dpy->fd_dpy, current_vblank_out);
if (err)
return err;
@@ -1095,7 +1096,7 @@ swap_vblank_state_transition(struct dri2_egl_surface *dri2_surf,
uint32_t flags = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
int err;
- err = display_request_vblank(dri2_dpy->fd, target_frame,
+ err = display_request_vblank(dri2_dpy->fd_dpy, target_frame,
flags, dri2_surf);
if (err) {
dri2_surf->swap_state = SWAP_ERROR;
@@ -1121,7 +1122,7 @@ swap_flip_state_transition(struct dri2_egl_surface *dri2_surf)
flags |= DRM_MODE_PAGE_FLIP_ASYNC;
}
- err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output,
+ err = display_output_flip(dri2_dpy->fd_dpy, &dri2_dpy->output,
dri2_surf->swap_data->fb_id, flags, dri2_surf);
if (err) {
dri2_surf->swap_state = SWAP_ERROR;
@@ -1141,7 +1142,7 @@ swap_poll_state_transition(struct dri2_egl_surface *dri2_surf)
int err;
/* dri2_surf->swap_state is being set inside the handler */
- err = drm_event_process(dri2_dpy->fd);
+ err = drm_event_process(dri2_dpy->fd_dpy);
if (err) {
dri2_surf->swap_state = SWAP_ERROR;
return err;
@@ -1296,7 +1297,7 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
handles[i] = (uint32_t) handle;
}
- return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height,
+ return !drmModeAddFB2WithModifiers(dri2_dpy->fd_dpy, width, height,
dri2_null_formats[format_idx].drm_format,
handles, pitches, offsets, modifiers,
fb_id_out, flags);
@@ -1486,7 +1487,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
if (dri2_dpy->in_formats_enabled) {
- ret = in_formats_get_modifiers(dri2_dpy->fd,
+ ret = in_formats_get_modifiers(dri2_dpy->fd_dpy,
dri2_dpy->output.in_formats_id,
dri2_null_formats[format_idx].drm_format,
&dri2_dpy->output.modifiers);
@@ -1564,7 +1565,7 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
goto err_destroy_surface;
}
- err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output,
+ err = display_output_modeset(dri2_dpy->fd_dpy, &dri2_dpy->output,
dri2_surf->front_buffer.fb_id);
if (err) {
_eglError(EGL_BAD_NATIVE_WINDOW, "window set mode");
@@ -1678,11 +1679,11 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image);
if (dri2_surf->front_buffer.fb_id)
- drmModeRmFB(dri2_dpy->fd, dri2_surf->front_buffer.fb_id);
+ drmModeRmFB(dri2_dpy->fd_dpy, dri2_surf->front_buffer.fb_id);
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (dri2_surf->color_buffers[i].fb_id)
- drmModeRmFB(dri2_dpy->fd, dri2_surf->color_buffers[i].fb_id);
+ drmModeRmFB(dri2_dpy->fd_dpy, dri2_surf->color_buffers[i].fb_id);
if (dri2_surf->color_buffers[i].dri_image)
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
}
@@ -1839,12 +1840,22 @@ dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
(void) loaderPrivate;
}
+static int
+dri2_null_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 __DRIimageLoaderExtension image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 2 },
+ .base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = dri2_null_image_get_buffers,
.flushFrontBuffer = dri2_null_flush_front_buffer,
.getCapability = dri2_null_get_capability,
+ .getDisplayFD = dri2_null_get_display_fd,
};
static const __DRIextension *image_loader_extensions[] = {
@@ -1873,12 +1884,74 @@ dri2_null_device_is_kms(int fd)
return is_kms;
}
+static bool
+dri2_null_try_device(_EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ if (!dri2_null_device_is_kms(dri2_dpy->fd_dpy))
+ return false;
+
+#if defined(NULL_DRI_DRIVER_NAME)
+ /* Skip devices not handled by NULL_DRI_DRIVER_NAME */
+ {
+ char *driver_name = loader_get_driver_for_fd(dri2_dpy->fd_dpy);
+ bool skip = !driver_name || !!strcmp(driver_name, NULL_DRI_DRIVER_NAME);
+
+ free(driver_name);
+
+ if (skip)
+ return false;
+ }
+#endif
+
+ dri2_dpy->fd = os_dupfd_cloexec(dri2_dpy->fd_dpy);
+ if (dri2_dpy->fd < 0) {
+ _eglLog(_EGL_WARNING, "DRI2: failed to dup display FD");
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
+ } else {
+ int fd_old;
+ bool is_different_gpu;
+
+ fd_old = dri2_dpy->fd;
+ dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
+ &is_different_gpu);
+ if (dri2_dpy->fd == fd_old) {
+ close (dri2_dpy->fd);
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
+ }
+ }
+
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
+ if (!dri2_dpy->driver_name)
+ return false;
+
+ if (dri2_load_driver_dri3(disp)) {
+ _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false);
+ if (!dev) {
+ dlclose(dri2_dpy->driver);
+ _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
+ } else {
+ dri2_dpy->loader_extensions = image_loader_extensions;
+ dri2_dpy->own_device = 1;
+ disp->Device = dev;
+ return true;
+ }
+ }
+
+ free(dri2_dpy->driver_name);
+ dri2_dpy->driver_name = NULL;
+
+ return false;
+}
+
static bool
dri2_null_probe_device(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
dri2_dpy->fd = -1;
+ dri2_dpy->fd_dpy = -1;
for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) {
char *card_path;
@@ -1886,32 +1959,20 @@ dri2_null_probe_device(_EGLDisplay *disp)
if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0)
continue;
- dri2_dpy->fd = loader_open_device(card_path);
+ dri2_dpy->fd_dpy = loader_open_device(card_path);
free(card_path);
- if (dri2_dpy->fd < 0)
+ if (dri2_dpy->fd_dpy < 0)
continue;
- if (dri2_null_device_is_kms(dri2_dpy->fd)) {
- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
- if (dri2_dpy->driver_name) {
- if (dri2_load_driver_dri3(disp)) {
- _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false);
- if (!dev) {
- dlclose(dri2_dpy->driver);
- _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
- } else {
- dri2_dpy->loader_extensions = image_loader_extensions;
- dri2_dpy->own_device = 1;
- disp->Device = dev;
- return true;
- }
- }
- free(dri2_dpy->driver_name);
- dri2_dpy->driver_name = NULL;
- }
- }
+ if (dri2_null_try_device(disp))
+ return true;
+
+ close(dri2_dpy->fd_dpy);
+
+ if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy)
+ close(dri2_dpy->fd);
- close(dri2_dpy->fd);
+ dri2_dpy->fd_dpy = -1;
dri2_dpy->fd = -1;
}
@@ -1972,7 +2033,7 @@ dri2_null_setup_swap_interval(_EGLDisplay *disp)
dri2_setup_swap_interval(disp, swap_max_interval);
- err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
+ err = drmGetCap(dri2_dpy->fd_dpy, DRM_CAP_ASYNC_PAGE_FLIP, &value);
if (err || value == 0) {
/* DRM/KMS does not support async page flip. In order to support
@@ -2020,7 +2081,7 @@ dri2_initialize_null(_EGLDisplay *disp)
* modesetting if not. If this succeeds then universal planes will also have
* been enabled.
*/
- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_ATOMIC, 1);
+ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_ATOMIC, 1);
dri2_dpy->atomic_enabled = !err;
if (!dri2_dpy->atomic_enabled) {
@@ -2028,7 +2089,7 @@ dri2_initialize_null(_EGLDisplay *disp)
* Enable universal planes so that we can get the pixel formats for the
* primary plane
*/
- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
if (err) {
_eglError(EGL_NOT_INITIALIZED, "failed to enable universal planes");
goto cleanup;
@@ -2064,7 +2125,7 @@ dri2_initialize_null(_EGLDisplay *disp)
dri2_dpy->image->createImageWithModifiers;
}
- if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output,
+ if (!display_output_init(dri2_dpy->fd_dpy, &dri2_dpy->output,
dri2_dpy->atomic_enabled,
prefer_in_formats,
&dri2_dpy->in_formats_enabled)) {
@@ -2098,7 +2159,7 @@ dri2_teardown_null(struct dri2_egl_display *dri2_dpy)
drmModeAtomicFree(dri2_dpy->output.atomic_state);
if (dri2_dpy->output.mode_blob_id)
- drmModeDestroyPropertyBlob(dri2_dpy->fd, dri2_dpy->output.mode_blob_id);
+ drmModeDestroyPropertyBlob(dri2_dpy->fd_dpy, dri2_dpy->output.mode_blob_id);
if (dri2_dpy->output.plane_prop_res) {
for (unsigned i = 0; dri2_dpy->output.plane_prop_res[i]; i++)
diff --git a/src/egl/meson.build b/src/egl/meson.build
index a08f1c71847..4aa9f5fb0de 100644
--- a/src/egl/meson.build
+++ b/src/egl/meson.build
@@ -151,6 +151,11 @@ elif with_platform_windows
link_for_egl += libgallium_wgl
endif
if with_platform_null
+ if null_dri_driver_name != ''
+ c_args_for_egl += [
+ '-DNULL_DRI_DRIVER_NAME="@0@"'.format(null_dri_driver_name),
+ ]
+ endif
files_egl += files('drivers/dri2/platform_null.c')
incs_for_egl += [inc_loader]
deps_for_egl += dep_libdrm
--
2.25.1