diff --git a/src/intercept/intercept.h b/src/intercept/intercept.h index edf6666..b31f6b1 100644 --- a/src/intercept/intercept.h +++ b/src/intercept/intercept.h @@ -13,6 +13,19 @@ #include +/** + * Attempt to handle snapd specific DRI path replacements to ensure that + * we can always load DRI modules for open source drivers. + * + * @note This must be run for all processes + * + * @param name The original search name + * @param soname Pointer to store the final soname in + * + * @returns True if we performed any redirection, to stop further processing. + */ +bool lsi_override_snapd_dri(const char *name, const char **soname); + /** * Attempt to handle snapd specific paths and perform any necessary redirections * for the solus-runtime-gaming based LSI snap package. diff --git a/src/intercept/main.c b/src/intercept/main.c index 5f40e11..db710b7 100644 --- a/src/intercept/main.c +++ b/src/intercept/main.c @@ -605,6 +605,9 @@ _nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *coo if (lsi_override_snapd_nvidia(name, &out_name)) { return (char *)out_name; } + if (lsi_override_snapd_dri(name, &out_name)) { + return (char *)out_name; + } #endif switch (work_mode) { case INTERCEPT_MODE_STEAM: diff --git a/src/intercept/snapd.c b/src/intercept/snapd.c index 6b495fa..d211555 100644 --- a/src/intercept/snapd.c +++ b/src/intercept/snapd.c @@ -153,6 +153,60 @@ bool lsi_override_snapd_nvidia(const char *name, const char **soname) return true; } +bool lsi_override_snapd_dri(const char *name, const char **soname) +{ + const char *lib_dir = NULL; + static char path_lookup[PATH_MAX]; + static char path_copy[PATH_MAX]; + char *small_name = NULL; + + /* Only mangle when we start looking for paths */ + if (!strstr(name, "/")) { + return false; + } + + /* Must be a proper dri lookup */ + if (!strstr(name, "_dri.so") && !strstr(name, "_drv_video.so")) { + return false; + } + + /* If this guy exists we don't actually care.. */ + if (lsi_file_exists(name)) { + return false; + } + +#if UINTPTR_MAX == 0xffffffffffffffff + /* 64-bit libdir */ + lib_dir = "/usr/lib/dri"; +#else + /* 32-bit libdir */ + lib_dir = "/usr/lib32/dri"; +#endif + + /* Grab the link name */ + if (!strcpy(path_copy, name)) { + return false; + } + small_name = basename(path_copy); + + if (snprintf(path_lookup, sizeof(path_lookup), "%s/%s", lib_dir, small_name) < 0) { + return false; + } + + /* Sod all we can do here */ + if (!lsi_file_exists(path_lookup)) { + lsi_log_error("Missing DRI file: %s (%s)", name, path_lookup); + return false; + } + + *soname = path_lookup; + lsi_log_debug("Enforcing snapd DRI links: \033[31;1m%s\033[0m -> \033[34;1m%s\033[0m", + name, + path_lookup); + + return true; +} + bool lsi_override_snapd_gl(const char *name, const char **soname) { for (size_t i = 0; i < ARRAY_SIZE(libgl_source_table); i++) {