From d11a6dec7e1a0cdfdddb2b537433ef348e625d94 Mon Sep 17 00:00:00 2001 From: Ludovico de Nittis <ludovico.denittis@collabora.com> Date: Thu, 12 Mar 2020 15:03:30 +0100 Subject: [PATCH] Add a special Mesa DRIs search path to cover Ubuntu 16.04 Ubuntu 16.04 is older than GLVND and it places Mesa loaders in ${libdir}/mesa and the DRIs in ${libdir}/dri. So if we find a loader in a path that ends with "/mesa" we try to look one directory above. Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com> --- steam-runtime-tools/graphics.c | 37 +++++++++++- tests/graphics.c | 54 ++++++++++++++++++ tests/meson.build | 1 + tests/mock-ubuntu-64-bit-inspect-library.c | 56 +++++++++++++++++++ .../ubuntu16/usr/lib/dri/radeonsi_dri.so | 0 .../lib/mock-ubuntu-64-bit/dri/i965_dri.so | 0 .../lib/mock-ubuntu-64-bit/dri/radeon_dri.so | 0 .../dri/radeonsi_drv_video.so | 0 .../usr/lib/mock-ubuntu-64-bit/libva.so.1 | 0 .../lib/mock-ubuntu-64-bit/mesa/libGL.so.1 | 0 .../vdpau/libvdpau_r600.so.1 | 1 + .../vdpau/libvdpau_r600.so.1.0.0 | 0 .../vdpau/libvdpau_radeonsi.so | 1 + .../vdpau/libvdpau_radeonsi.so.1 | 1 + .../vdpau/libvdpau_radeonsi.so.1.0.0 | 0 15 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 tests/mock-ubuntu-64-bit-inspect-library.c create mode 100644 tests/sysroots/ubuntu16/usr/lib/dri/radeonsi_dri.so create mode 100644 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/i965_dri.so create mode 100644 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/radeon_dri.so create mode 100644 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/radeonsi_drv_video.so create mode 100644 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/libva.so.1 create mode 100644 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/mesa/libGL.so.1 create mode 120000 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_r600.so.1 create mode 100644 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_r600.so.1.0.0 create mode 120000 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so create mode 120000 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so.1 create mode 100644 tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so.1.0.0 diff --git a/steam-runtime-tools/graphics.c b/steam-runtime-tools/graphics.c index c51a9e434..f06d36833 100644 --- a/steam-runtime-tools/graphics.c +++ b/steam-runtime-tools/graphics.c @@ -2600,6 +2600,21 @@ _srt_get_extra_modules_directory (const gchar *library_search_path, g_return_val_if_fail (multiarch_tuple != NULL, NULL); dir = g_strdup (library_search_path); + + /* If the loader path ends with "/mesa" we try to look one directory above. + * For example this is how Ubuntu 16.04 works, the loaders are in ${libdir}/mesa + * and the DRI modules in ${libdir}/dri */ + if (g_str_has_suffix (dir, "/mesa")) + { + dir[strlen (dir) - strlen ("/mesa") + 1] = '\0'; + /* Remove the trailing slash */ + if (g_strcmp0 (dir, "/") != 0) + dir[strlen (dir) - 1] = '\0'; + } + + ret = g_list_prepend (ret, g_build_filename (dir, "dri", NULL)); + g_debug ("Looking in lib directory: %s", (const char *) ret->data); + lib_multiarch = g_strdup_printf ("/lib/%s", multiarch_tuple); if (!g_str_has_suffix (dir, lib_multiarch)) @@ -2632,6 +2647,8 @@ _srt_get_extra_modules_directory (const gchar *library_search_path, ret = g_list_prepend (ret, g_build_filename (dir, libqual, "dri", NULL)); g_debug ("Looking in libQUAL directory: %s", (const char *) ret->data); + ret = g_list_sort (ret, (GCompareFunc) strcmp); + out: g_free (lib_multiarch); g_free (dir); @@ -2810,9 +2827,11 @@ _srt_get_modules_full (const char *sysroot, static const char *const vdpau_loaders[] = { "libvdpau.so.1", NULL }; const gchar *env_override; const gchar *drivers_path; + const gchar *force_elf_class = NULL; gchar *flatpak_info; GHashTable *drivers_set; gboolean is_extra = FALSE; + int driver_class; g_return_if_fail (multiarch_tuple != NULL); g_return_if_fail (drivers_out != NULL); @@ -2846,6 +2865,11 @@ _srt_get_modules_full (const char *sysroot, else drivers_path = g_getenv (env_override); + if (envp != NULL) + force_elf_class = g_environ_getenv (envp, "SRT_TEST_FORCE_ELF"); + else + force_elf_class = g_getenv ("SRT_TEST_FORCE_ELF"); + if (sysroot == NULL) sysroot = "/"; @@ -3017,7 +3041,18 @@ _srt_get_modules_full (const char *sysroot, libdir_driver, is_extra, module, drivers_out); } - int driver_class = _srt_get_library_class (driver_canonical_path); + if (force_elf_class) + { + if (g_strcmp0 (force_elf_class, "64") == 0) + driver_class = ELFCLASS64; + else + driver_class = ELFCLASS32; + } + else + { + driver_class = _srt_get_library_class (driver_canonical_path); + } + const GList *this_extra_path; if (driver_class != ELFCLASSNONE) { diff --git a/tests/graphics.c b/tests/graphics.c index 3aa913f58..a693b8586 100644 --- a/tests/graphics.c +++ b/tests/graphics.c @@ -28,6 +28,7 @@ #include <errno.h> #include <string.h> #include <unistd.h> +#include <libelf.h> #include <glib.h> #include <glib/gstdio.h> @@ -2027,6 +2028,57 @@ test_dri_fedora (Fixture *f, g_strfreev (envp); } +static void +test_dri_ubuntu16 (Fixture *f, + gconstpointer context) +{ + SrtSystemInfo *info; + gchar **envp; + gchar *sysroot; + GList *dri; + GList *va_api; + const gchar *multiarch_tuples[] = {"mock-ubuntu-64-bit", NULL}; + const gchar *dri_suffixes[] = {NULL}; + const gchar *dri_suffixes_extra[] = {"/lib/dri/radeonsi_dri.so", + "/lib/mock-ubuntu-64-bit/dri/i965_dri.so", + "/lib/mock-ubuntu-64-bit/dri/radeon_dri.so", + NULL}; + const gchar *va_api_suffixes[] = {"/lib/mock-ubuntu-64-bit/dri/radeonsi_drv_video.so", + NULL}; + + sysroot = g_build_filename (f->srcdir, "sysroots", "ubuntu16", NULL); + envp = g_get_environ (); + envp = g_environ_setenv (envp, "SRT_TEST_SYSROOT", sysroot, TRUE); + envp = g_environ_setenv (envp, "SRT_TEST_FORCE_ELF", "64", TRUE); + envp = g_environ_unsetenv (envp, "LIBGL_DRIVERS_PATH"); + envp = g_environ_unsetenv (envp, "LIBVA_DRIVERS_PATH"); + + info = srt_system_info_new (NULL); + srt_system_info_set_environ (info, envp); + srt_system_info_set_sysroot (info, sysroot); + srt_system_info_set_helpers_path (info, f->builddir); + + dri = srt_system_info_list_dri_drivers (info, multiarch_tuples[0], SRT_DRIVER_FLAGS_NONE); + check_list_suffixes (dri, dri_suffixes, SRT_GRAPHICS_DRI_MODULE); + g_list_free_full (dri, g_object_unref); + + dri = srt_system_info_list_dri_drivers (info, multiarch_tuples[0], SRT_DRIVER_FLAGS_INCLUDE_ALL); + check_list_suffixes (dri, dri_suffixes_extra, SRT_GRAPHICS_DRI_MODULE); + g_list_free_full (dri, g_object_unref); + + va_api = srt_system_info_list_va_api_drivers (info, multiarch_tuples[0], SRT_DRIVER_FLAGS_NONE); + check_list_suffixes (va_api, va_api_suffixes, SRT_GRAPHICS_VAAPI_MODULE); + g_list_free_full (va_api, g_object_unref); + + va_api = srt_system_info_list_va_api_drivers (info, multiarch_tuples[0], SRT_DRIVER_FLAGS_INCLUDE_ALL); + check_list_suffixes (va_api, va_api_suffixes, SRT_GRAPHICS_VAAPI_MODULE); + g_list_free_full (va_api, g_object_unref); + + g_object_unref (info); + g_free (sysroot); + g_strfreev (envp); +} + static void test_dri_with_env (Fixture *f, gconstpointer context) @@ -2578,6 +2630,8 @@ main (int argc, setup, test_dri_debian10, teardown); g_test_add ("/graphics/dri/fedora", Fixture, NULL, setup, test_dri_fedora, teardown); + g_test_add ("/graphics/dri/ubuntu16", Fixture, NULL, + setup, test_dri_ubuntu16, teardown); g_test_add ("/graphics/dri/with_env", Fixture, NULL, setup, test_dri_with_env, teardown); g_test_add ("/graphics/dri/flatpak", Fixture, NULL, diff --git a/tests/meson.build b/tests/meson.build index 9fded0f17..9f03b5b25 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -230,6 +230,7 @@ foreach helper : [ 'mock-good-wflinfo', 'mock-mixed-check-gl', 'mock-software-wflinfo', + 'mock-ubuntu-64-bit-inspect-library', ] executable( helper, diff --git a/tests/mock-ubuntu-64-bit-inspect-library.c b/tests/mock-ubuntu-64-bit-inspect-library.c new file mode 100644 index 000000000..4e7db2cee --- /dev/null +++ b/tests/mock-ubuntu-64-bit-inspect-library.c @@ -0,0 +1,56 @@ +/* + * Copyright © 2019 Collabora Ltd. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <glib.h> + +int +main (int argc, + char **argv) +{ + g_return_val_if_fail (argc == 2, EXIT_FAILURE); + + gchar **envp = g_get_environ (); + gchar *path = NULL; + + /* If we need to locate "libGL.so.1" we return a canonical Ubuntu 16.04 style 64 bit folder, under + * the "mesa" subfolder */ + if (g_strcmp0 (argv[1], "libGL.so.1") == 0) + path = g_build_filename (g_environ_getenv (envp, "SRT_TEST_SYSROOT"), "usr", "lib", + "mock-ubuntu-64-bit", "mesa", argv[1], NULL); + else + path = g_build_filename (g_environ_getenv (envp, "SRT_TEST_SYSROOT"), "usr", "lib", + "mock-ubuntu-64-bit", argv[1], NULL); + + /* Return a JSON like if we found the given soname */ + printf ("{\n\t\"%s\": {\n" + "\t\t\"path\": \"%s\"\n" + "\t}\n" + "}\n", argv[1], path); + g_free (path); + g_strfreev (envp); + return 0; +} diff --git a/tests/sysroots/ubuntu16/usr/lib/dri/radeonsi_dri.so b/tests/sysroots/ubuntu16/usr/lib/dri/radeonsi_dri.so new file mode 100644 index 000000000..e69de29bb diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/i965_dri.so b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/i965_dri.so new file mode 100644 index 000000000..e69de29bb diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/radeon_dri.so b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/radeon_dri.so new file mode 100644 index 000000000..e69de29bb diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/radeonsi_drv_video.so b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/dri/radeonsi_drv_video.so new file mode 100644 index 000000000..e69de29bb diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/libva.so.1 b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/libva.so.1 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/mesa/libGL.so.1 b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/mesa/libGL.so.1 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_r600.so.1 b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_r600.so.1 new file mode 120000 index 000000000..664517965 --- /dev/null +++ b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_r600.so.1 @@ -0,0 +1 @@ +libvdpau_r600.so.1.0.0 \ No newline at end of file diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_r600.so.1.0.0 b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_r600.so.1.0.0 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so new file mode 120000 index 000000000..7d720b573 --- /dev/null +++ b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so @@ -0,0 +1 @@ +libvdpau_radeonsi.so.1.0.0 \ No newline at end of file diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so.1 b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so.1 new file mode 120000 index 000000000..7d720b573 --- /dev/null +++ b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so.1 @@ -0,0 +1 @@ +libvdpau_radeonsi.so.1.0.0 \ No newline at end of file diff --git a/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so.1.0.0 b/tests/sysroots/ubuntu16/usr/lib/mock-ubuntu-64-bit/vdpau/libvdpau_radeonsi.so.1.0.0 new file mode 100644 index 000000000..e69de29bb -- GitLab