diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c index 465b39409b7a01e5d00b49812420b11571160d90..d5cd0f88b743fb5b9f9cdef7c19f013298c7e277 100644 --- a/pressure-vessel/runtime.c +++ b/pressure-vessel/runtime.c @@ -29,6 +29,8 @@ #include "libglnx/libglnx.h" #include <steam-runtime-tools/steam-runtime-tools.h> + +#include "steam-runtime-tools/graphics-internal.h" #include "steam-runtime-tools/resolve-in-sysroot-internal.h" #include "steam-runtime-tools/utils-internal.h" @@ -3842,10 +3844,12 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self, xdg_data_dirs = g_environ_getenv (self->original_environ, "XDG_DATA_DIRS"); override_share = g_build_filename (self->overrides_in_container, "share", NULL); - if (xdg_data_dirs != NULL) - prepended_data_dirs = g_strdup_printf ("%s:%s", override_share, xdg_data_dirs); - else - prepended_data_dirs = g_steal_pointer (&override_share); + /* Reference: + * https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html */ + if (xdg_data_dirs == NULL) + xdg_data_dirs = "/usr/local/share:/usr/share"; + + prepended_data_dirs = g_strdup_printf ("%s:%s", override_share, xdg_data_dirs); pv_environ_lock_env (container_env, "XDG_DATA_DIRS", prepended_data_dirs); @@ -3952,6 +3956,48 @@ pv_runtime_bind (PvRuntime *self, self->adverb_in_container = "/run/pressure-vessel/pv-from-host/bin/pressure-vessel-adverb"; } + if ((self->flags & PV_RUNTIME_FLAGS_IMPORT_VULKAN_LAYERS) + && exports != NULL) + { + /* We have added our imported Vulkan layers to the search path, + * but we can't just remove ~/.local/share, etc. from the search + * path without breaking unrelated users of the XDG basedirs spec, + * such as .desktop files and icons. Mask any remaining Vulkan + * layers by mounting empty directories over the top. */ + static const char * const layer_suffixes[] = + { + _SRT_GRAPHICS_EXPLICIT_VULKAN_LAYER_SUFFIX, + _SRT_GRAPHICS_IMPLICIT_VULKAN_LAYER_SUFFIX, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (layer_suffixes); i++) + { + g_auto(GStrv) search_path = NULL; + const char *suffix = layer_suffixes[i]; + gsize j; + + search_path = _srt_graphics_get_vulkan_search_paths ("/", + self->original_environ, + multiarch_tuples, + suffix); + + for (j = 0; search_path != NULL && search_path[j] != NULL; j++) + { + const char *dir = search_path[j]; + + /* We are mounting our own runtime over /usr anyway, so + * ignore those */ + if (flatpak_has_path_prefix (dir, "/usr")) + continue; + + /* Otherwise, if the directory exists, mask it */ + if (g_file_test (dir, G_FILE_TEST_IS_DIR)) + flatpak_exports_add_path_tmpfs (exports, dir); + } + } + } + /* Some games detect that they have been run outside the Steam Runtime * and try to re-run themselves via Steam. Trick them into thinking * they are in the LD_LIBRARY_PATH Steam Runtime. diff --git a/steam-runtime-tools/graphics-internal.h b/steam-runtime-tools/graphics-internal.h index 55300797b890ece83d9b5def27fede5db9a9a76c..4ab5ac8026083ed943a6d146fd4f4ac5032a87ca 100644 --- a/steam-runtime-tools/graphics-internal.h +++ b/steam-runtime-tools/graphics-internal.h @@ -305,3 +305,13 @@ GList *_srt_dri_driver_get_from_report (JsonObject *json_obj); GList *_srt_va_api_driver_get_from_report (JsonObject *json_obj); GList *_srt_vdpau_driver_get_from_report (JsonObject *json_obj); GList *_srt_glx_icd_get_from_report (JsonObject *json_obj); + +G_GNUC_INTERNAL +gchar ** _srt_graphics_get_vulkan_search_paths (const char *sysroot, + gchar **envp, + const char * const *multiarch_tuples, + const char *suffix); + +#define _SRT_GRAPHICS_EXPLICIT_VULKAN_LAYER_SUFFIX "vulkan/explicit_layer.d" +#define _SRT_GRAPHICS_IMPLICIT_VULKAN_LAYER_SUFFIX "vulkan/implicit_layer.d" +#define _SRT_GRAPHICS_VULKAN_ICD_SUFFIX "vulkan/icd.d" diff --git a/steam-runtime-tools/graphics.c b/steam-runtime-tools/graphics.c index 075e6112732e8bd4d1bd34a6d07c7382e3f3be62..6192501095260a63e6f508dbeb08036cfdf46614 100644 --- a/steam-runtime-tools/graphics.c +++ b/steam-runtime-tools/graphics.c @@ -5588,8 +5588,6 @@ vulkan_icd_load_json_cb (const char *sysroot, vulkan_icd_load_json (sysroot, filename, user_data); } -#define VULKAN_ICD_SUFFIX "vulkan/icd.d" - /* * Return the ${sysconfdir} that we assume the Vulkan loader has. * See get_glvnd_sysconfdir(). @@ -5600,11 +5598,11 @@ get_vulkan_sysconfdir (void) return "/etc"; } -static gchar ** -get_vulkan_search_paths (const char *sysroot, - gchar **envp, - const char * const *multiarch_tuples, - const char *suffix) +gchar ** +_srt_graphics_get_vulkan_search_paths (const char *sysroot, + gchar **envp, + const char * const *multiarch_tuples, + const char *suffix) { GPtrArray *search_paths = g_ptr_array_new (); g_auto(GStrv) dirs = NULL; @@ -5748,8 +5746,10 @@ _srt_load_vulkan_icds (const char *sysroot, } else { - g_auto(GStrv) search_paths = get_vulkan_search_paths (sysroot, envp, multiarch_tuples, - VULKAN_ICD_SUFFIX); + g_auto(GStrv) search_paths = _srt_graphics_get_vulkan_search_paths (sysroot, + envp, + multiarch_tuples, + _SRT_GRAPHICS_VULKAN_ICD_SUFFIX); load_json_dirs (sysroot, search_paths, NULL, READDIR_ORDER, vulkan_icd_load_json_cb, &ret); } @@ -6516,9 +6516,6 @@ vulkan_layer_load_json_cb (const char *sysroot, vulkan_layer_load_json (sysroot, filename, user_data); } -#define EXPLICIT_VULKAN_LAYER_SUFFIX "vulkan/explicit_layer.d" -#define IMPLICIT_VULKAN_LAYER_SUFFIX "vulkan/implicit_layer.d" - /* * _srt_load_vulkan_layers: * @sysroot: (not nullable): The root directory, usually `/` @@ -6546,9 +6543,9 @@ _srt_load_vulkan_layers (const char *sysroot, g_return_val_if_fail (envp != NULL, NULL); if (explicit) - suffix = EXPLICIT_VULKAN_LAYER_SUFFIX; + suffix = _SRT_GRAPHICS_EXPLICIT_VULKAN_LAYER_SUFFIX; else - suffix = IMPLICIT_VULKAN_LAYER_SUFFIX; + suffix = _SRT_GRAPHICS_IMPLICIT_VULKAN_LAYER_SUFFIX; value = g_environ_getenv (envp, "VK_LAYER_PATH"); @@ -6564,7 +6561,8 @@ _srt_load_vulkan_layers (const char *sysroot, } else { - search_paths = get_vulkan_search_paths (sysroot, envp, NULL, suffix); + search_paths = _srt_graphics_get_vulkan_search_paths (sysroot, envp, + NULL, suffix); g_debug ("SEARCH PATHS %s", search_paths[0]); load_json_dirs (sysroot, search_paths, NULL, _srt_indirect_strcmp0, vulkan_layer_load_json_cb, &ret);