summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--loader/loader.c115
-rw-r--r--loader/vk_loader_platform.h44
3 files changed, 106 insertions, 62 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d3037f82..494dd594 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -286,17 +286,10 @@ if(NOT WIN32)
include(GNUInstallDirs)
add_definitions(-DSYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}")
- add_definitions(-DDATADIR="${CMAKE_INSTALL_FULL_DATADIR}")
-
# Make sure /etc is searched by the loader
- if (NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc"))
+ if(NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc"))
add_definitions(-DEXTRASYSCONFDIR="/etc")
endif()
-
- # Make sure /usr/share is searched by the loader
- if (NOT (CMAKE_INSTALL_FULL_DATADIR STREQUAL "/usr/share"))
- add_definitions(-DEXTRADATADIR="/usr/share")
- endif()
endif()
if(UNIX)
diff --git a/loader/loader.c b/loader/loader.c
index 2875af13..81c37c4c 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -30,6 +30,7 @@
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
+#include <stddef.h>
#include <sys/types.h>
#if defined(_WIN32)
@@ -2585,7 +2586,7 @@ static void loader_add_layer_properties(const struct loader_instance *inst, stru
* Linux Layer| dirs | dirs
*/
static VkResult loader_get_manifest_files(const struct loader_instance *inst, const char *env_override, const char *source_override,
- bool is_layer, bool warn_if_not_present, const char *location, const char *home_location,
+ bool is_layer, bool warn_if_not_present, const char *location, const char *relative_location,
struct loader_manifest_files *out_files) {
const char * override = NULL;
char *override_getenv = NULL;
@@ -2617,9 +2618,9 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
}
#if !defined(_WIN32)
- if (location == NULL && home_location == NULL) {
+ if (relative_location == NULL) {
#else
- home_location = NULL;
+ relative_location = NULL;
if (location == NULL) {
#endif
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -2638,16 +2639,92 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
// Make a copy of the input we are using so it is not modified
// Also handle getting the location(s) from registry on Windows
if (override == NULL) {
- loc = loader_stack_alloc(strlen(location) + 1);
+ size_t loc_size = 0;
+#if !defined(_WIN32)
+ const char *xdgconfdirs = secure_getenv("XDG_CONFIG_DIRS");
+ const char *xdgdatadirs = secure_getenv("XDG_DATA_DIRS");
+ if (xdgconfdirs == NULL || xdgconfdirs[0] == '\0')
+ xdgconfdirs = "/etc/xdg";
+ if (xdgdatadirs == NULL || xdgdatadirs[0] == '\0')
+ xdgdatadirs = "/usr/local/share:/usr/share";
+ const size_t rel_size = strlen(relative_location);
+ // Leave space for trailing separators
+ loc_size += strlen(xdgconfdirs) + strlen(xdgdatadirs) + 2*rel_size + 2;
+ for (const char *x = xdgconfdirs; *x; ++x)
+ if (*x == PATH_SEPARATOR) loc_size += rel_size;
+ for (const char *x = xdgdatadirs; *x; ++x)
+ if (*x == PATH_SEPARATOR) loc_size += rel_size;
+ loc_size += strlen(SYSCONFDIR) + rel_size + 1;
+#if defined(EXTRASYSCONFDIR)
+ loc_size += strlen(EXTRASYSCONFDIR) + rel_size + 1;
+#endif
+#else
+ loc_size += strlen(location) + 1;
+#endif
+ loc = loader_stack_alloc(loc_size);
if (loc == NULL) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"loader_get_manifest_files: Failed to allocate "
"%d bytes for manifest file location.",
- strlen(location));
+ loc_size);
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
- strcpy(loc, location);
+ char *loc_write = loc;
+#if !defined(_WIN32)
+ const char *loc_read;
+
+ loc_read = &xdgconfdirs[0];
+ for (const char *x = loc_read;; ++x) {
+ if (*x == PATH_SEPARATOR || *x == '\0') {
+ const size_t s = x - loc_read;
+ memcpy(loc_write, loc_read, s);
+ loc_write += s;
+ memcpy(loc_write, relative_location, rel_size);
+ loc_write += rel_size;
+ *loc_write++ = PATH_SEPARATOR;
+ if (*x == 0)
+ break;
+ loc_read = ++x;
+ }
+ }
+
+ memcpy(loc_write, SYSCONFDIR, strlen(SYSCONFDIR));
+ loc_write += strlen(SYSCONFDIR);
+ memcpy(loc_write, relative_location, rel_size);
+ loc_write += rel_size;
+ *loc_write++ = PATH_SEPARATOR;
+
+#if defined(EXTRASYSCONFDIR)
+ memcpy(loc_write, EXTRASYSCONFDIR, strlen(EXTRASYSCONFDIR));
+ loc_write += strlen(EXTRASYSCONFDIR);
+ memcpy(loc_write, relative_location, rel_size);
+ loc_write += rel_size;
+ *loc_write++ = PATH_SEPARATOR;
+#endif
+
+ loc_read = &xdgdatadirs[0];
+ for (const char *x = loc_read;; ++x) {
+ if (*x == PATH_SEPARATOR || *x == '\0') {
+ const size_t s = x - loc_read;
+ memcpy(loc_write, loc_read, s);
+ loc_write += s;
+ memcpy(loc_write, relative_location, rel_size);
+ loc_write += rel_size;
+ *loc_write++ = PATH_SEPARATOR;
+ if (*x == 0)
+ break;
+ loc_read = ++x;
+ }
+ }
+ --loc_write;
+#else
+ memcpy(loc_write, location, strlen(location));
+ loc_write += strlen(location);
+#endif
+ assert(loc_write - loc < (ptrdiff_t)loc_size);
+ *loc_write = '\0';
+
#if defined(_WIN32)
VkResult reg_result = loaderGetRegistryFiles(inst, loc, &reg);
if (VK_SUCCESS != reg_result || NULL == reg) {
@@ -2786,11 +2863,11 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
}
file = next_file;
#if !defined(_WIN32)
- if (home_location != NULL && (next_file == NULL || *next_file == '\0') && override == NULL) {
+ if (relative_location != NULL && (next_file == NULL || *next_file == '\0') && override == NULL) {
char *xdgdatahome = secure_getenv("XDG_DATA_HOME");
size_t len;
if (xdgdatahome != NULL) {
- char *home_loc = loader_stack_alloc(strlen(xdgdatahome) + 2 + strlen(home_location));
+ char *home_loc = loader_stack_alloc(strlen(xdgdatahome) + 2 + strlen(relative_location));
if (home_loc == NULL) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"loader_get_manifest_files: Failed to allocate "
@@ -2800,15 +2877,15 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
}
strcpy(home_loc, xdgdatahome);
// Add directory separator if needed
- if (home_location[0] != DIRECTORY_SYMBOL) {
+ if (relative_location[0] != DIRECTORY_SYMBOL) {
len = strlen(home_loc);
home_loc[len] = DIRECTORY_SYMBOL;
home_loc[len + 1] = '\0';
}
- strcat(home_loc, home_location);
+ strcat(home_loc, relative_location);
file = home_loc;
next_file = loader_get_next_path(file);
- home_location = NULL;
+ relative_location = NULL;
loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Searching the following path for manifest files: %s\n",
home_loc);
@@ -2817,7 +2894,7 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
} else {
char *home = secure_getenv("HOME");
if (home != NULL) {
- char *home_loc = loader_stack_alloc(strlen(home) + 16 + strlen(home_location));
+ char *home_loc = loader_stack_alloc(strlen(home) + 16 + strlen(relative_location));
if (home_loc == NULL) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"loader_get_manifest_files: Failed to allocate "
@@ -2834,15 +2911,15 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
}
strcat(home_loc, ".local/share");
- if (home_location[0] != DIRECTORY_SYMBOL) {
+ if (relative_location[0] != DIRECTORY_SYMBOL) {
len = strlen(home_loc);
home_loc[len] = DIRECTORY_SYMBOL;
home_loc[len + 1] = '\0';
}
- strcat(home_loc, home_location);
+ strcat(home_loc, relative_location);
file = home_loc;
next_file = loader_get_next_path(file);
- home_location = NULL;
+ relative_location = NULL;
loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Searching the following path for manifest files: %s\n",
home_loc);
@@ -2914,7 +2991,7 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
}
// Get a list of manifest files for ICDs
- res = loader_get_manifest_files(inst, "VK_ICD_FILENAMES", NULL, false, true, DEFAULT_VK_DRIVERS_INFO, HOME_VK_DRIVERS_INFO,
+ res = loader_get_manifest_files(inst, "VK_ICD_FILENAMES", NULL, false, true, DEFAULT_VK_DRIVERS_INFO, RELATIVE_VK_DRIVERS_INFO,
&manifest_files);
if (VK_SUCCESS != res || manifest_files.count == 0) {
goto out;
@@ -3128,14 +3205,14 @@ void loader_layer_scan(const struct loader_instance *inst, struct loader_layer_l
// Get a list of manifest files for explicit layers
if (VK_SUCCESS != loader_get_manifest_files(inst, LAYERS_PATH_ENV, LAYERS_SOURCE_PATH, true, true, DEFAULT_VK_ELAYERS_INFO,
- HOME_VK_ELAYERS_INFO, &manifest_files[0])) {
+ RELATIVE_VK_ELAYERS_INFO, &manifest_files[0])) {
goto out;
}
// Get a list of manifest files for any implicit layers
// Pass NULL for environment variable override - implicit layers are not
// overridden by LAYERS_PATH_ENV
- if (VK_SUCCESS != loader_get_manifest_files(inst, NULL, NULL, true, false, DEFAULT_VK_ILAYERS_INFO, HOME_VK_ILAYERS_INFO,
+ if (VK_SUCCESS != loader_get_manifest_files(inst, NULL, NULL, true, false, DEFAULT_VK_ILAYERS_INFO, RELATIVE_VK_ILAYERS_INFO,
&manifest_files[1])) {
goto out;
}
@@ -3198,7 +3275,7 @@ void loader_implicit_layer_scan(const struct loader_instance *inst, struct loade
// Pass NULL for environment variable override - implicit layers are not
// overridden by LAYERS_PATH_ENV
VkResult res =
- loader_get_manifest_files(inst, NULL, NULL, true, false, DEFAULT_VK_ILAYERS_INFO, HOME_VK_ILAYERS_INFO, &manifest_files);
+ loader_get_manifest_files(inst, NULL, NULL, true, false, DEFAULT_VK_ILAYERS_INFO, RELATIVE_VK_ILAYERS_INFO, &manifest_files);
if (VK_SUCCESS != res || manifest_files.count == 0) {
return;
}
diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h
index 8a70865d..9af64a9e 100644
--- a/loader/vk_loader_platform.h
+++ b/loader/vk_loader_platform.h
@@ -57,35 +57,9 @@
#define VULKAN_ILAYERCONF_DIR "implicit_layer.d"
#define VULKAN_LAYER_DIR "layer"
-#if defined(EXTRASYSCONFDIR)
-#define EXTRA_DRIVERS_SYSCONFDIR_INFO ":" EXTRASYSCONFDIR VULKAN_DIR VULKAN_ICDCONF_DIR
-#define EXTRA_ELAYERS_SYSCONFDIR_INFO ":" EXTRASYSCONFDIR VULKAN_DIR VULKAN_ELAYERCONF_DIR
-#define EXTRA_ILAYERS_SYSCONFDIR_INFO ":" EXTRASYSCONFDIR VULKAN_DIR VULKAN_ILAYERCONF_DIR
-#else
-#define EXTRA_DRIVERS_SYSCONFDIR_INFO
-#define EXTRA_ELAYERS_SYSCONFDIR_INFO
-#define EXTRA_ILAYERS_SYSCONFDIR_INFO
-#endif
-
-#if defined(EXTRADATADIR)
-#define EXTRA_DRIVERS_DATADIR_INFO ":" EXTRADATADIR VULKAN_DIR VULKAN_ICDCONF_DIR
-#define EXTRA_ELAYERS_DATADIR_INFO ":" EXTRADATADIR VULKAN_DIR VULKAN_ELAYERCONF_DIR
-#define EXTRA_ILAYERS_DATADIR_INFO ":" EXTRADATADIR VULKAN_DIR VULKAN_ILAYERCONF_DIR
-#else
-#define EXTRA_DRIVERS_DATADIR_INFO
-#define EXTRA_ELAYERS_DATADIR_INFO
-#define EXTRA_ILAYERS_DATADIR_INFO
-#endif
-
-#define DEFAULT_VK_DRIVERS_INFO \
- SYSCONFDIR VULKAN_DIR VULKAN_ICDCONF_DIR \
- ":" DATADIR VULKAN_DIR VULKAN_ICDCONF_DIR EXTRA_DRIVERS_SYSCONFDIR_INFO EXTRA_DRIVERS_DATADIR_INFO
-#define DEFAULT_VK_ELAYERS_INFO \
- SYSCONFDIR VULKAN_DIR VULKAN_ELAYERCONF_DIR \
- ":" DATADIR VULKAN_DIR VULKAN_ELAYERCONF_DIR EXTRA_ELAYERS_SYSCONFDIR_INFO EXTRA_ELAYERS_DATADIR_INFO
-#define DEFAULT_VK_ILAYERS_INFO \
- SYSCONFDIR VULKAN_DIR VULKAN_ILAYERCONF_DIR \
- ":" DATADIR VULKAN_DIR VULKAN_ILAYERCONF_DIR EXTRA_ILAYERS_SYSCONFDIR_INFO EXTRA_ILAYERS_DATADIR_INFO
+#define DEFAULT_VK_DRIVERS_INFO ""
+#define DEFAULT_VK_ELAYERS_INFO ""
+#define DEFAULT_VK_ILAYERS_INFO ""
#define DEFAULT_VK_DRIVERS_PATH ""
#if !defined(DEFAULT_VK_LAYERS_PATH)
@@ -97,9 +71,9 @@
#endif
#define LAYERS_PATH_ENV "VK_LAYER_PATH"
-#define HOME_VK_DRIVERS_INFO VULKAN_DIR VULKAN_ICDCONF_DIR
-#define HOME_VK_ELAYERS_INFO VULKAN_DIR VULKAN_ELAYERCONF_DIR
-#define HOME_VK_ILAYERS_INFO VULKAN_DIR VULKAN_ILAYERCONF_DIR
+#define RELATIVE_VK_DRIVERS_INFO VULKAN_DIR VULKAN_ICDCONF_DIR
+#define RELATIVE_VK_ELAYERS_INFO VULKAN_DIR VULKAN_ELAYERCONF_DIR
+#define RELATIVE_VK_ILAYERS_INFO VULKAN_DIR VULKAN_ILAYERCONF_DIR
// C99:
#define PRINTF_SIZE_T_SPECIFIER "%zu"
@@ -201,9 +175,9 @@ static inline void loader_platform_thread_cond_broadcast(loader_platform_thread_
#define LAYERS_SOURCE_PATH NULL
#endif
#define LAYERS_PATH_ENV "VK_LAYER_PATH"
-#define HOME_VK_DRIVERS_INFO ""
-#define HOME_VK_ELAYERS_INFO ""
-#define HOME_VK_ILAYERS_INFO ""
+#define RELATIVE_VK_DRIVERS_INFO ""
+#define RELATIVE_VK_ELAYERS_INFO ""
+#define RELATIVE_VK_ILAYERS_INFO ""
#define PRINTF_SIZE_T_SPECIFIER "%Iu"
// File IO