diff --git a/steam-runtime-tools/graphics.c b/steam-runtime-tools/graphics.c index c51a9e434f9bf0b3749e63f1203cb4928b8864e6..f06d368337d4f23a3a22ee8de182758f8eea2f98 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 3aa913f5806ce5735560b4f042921af0ca8d04e9..a693b8586452b7a396b45ddca3c444e22a19a876 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 9fded0f179fc0f4a77109678869d6fd6eef76236..9f03b5b25b62687c05f3eb5bb03534648d903f9c 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 0000000000000000000000000000000000000000..4e7db2cee5190d626eaf4cb0e41382d75db0202c --- /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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 0000000000000000000000000000000000000000..6645179651d23785fd525c99a83c87d62c24387c --- /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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 0000000000000000000000000000000000000000..7d720b5733249de86ebe74f714e3d4168e9b47b1 --- /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 0000000000000000000000000000000000000000..7d720b5733249de86ebe74f714e3d4168e9b47b1 --- /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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391