Add "additive" environment variables
authorMark Young <marky@lunarg.com>
Tue, 4 Jan 2022 18:45:18 +0000 (11:45 -0700)
committerMark Young <marky@lunarg.com>
Fri, 4 Mar 2022 22:38:46 +0000 (15:38 -0700)
Add "additive" environment variables for adding additional layer
paths or driver JSON files instead of replacing default ones.

Also, rename VK_ICD_FILENAMES to VK_DRIVER_FILES since we're trying
to remove references to ICDs because software driver implementations
of Vulkan aren't ICDs (but continue to support the old name as well).

Added documentation around these changes to reflect the new name and
the new variables.

20 files changed:
BUILD.md
docs/LoaderDriverInterface.md
docs/LoaderInterfaceArchitecture.md
docs/LoaderLayerInterface.md
loader/loader.c
loader/loader.h
loader/loader_common.h
loader/loader_windows.c
loader/loader_windows.h
loader/trampoline.c
loader/vk_loader_platform.h
tests/CMakeLists.txt
tests/framework/README.md
tests/framework/layer/wrap_objects.cpp
tests/framework/test_environment.cpp
tests/framework/test_environment.h
tests/loader_envvar_tests.cpp [new file with mode: 0644]
tests/loader_regression_tests.cpp
tests/loader_testing_main.cpp
tests/loader_version_tests.cpp

index 45972f4dbc448c39bb2f634057a8a813bca557f1..215c4f0ad6b9d1a15abe68c8de9091a5f661a99d 100644 (file)
--- a/BUILD.md
+++ b/BUILD.md
@@ -721,7 +721,7 @@ Before you run these tests, you will need to clone and build the
 
 You will also need to direct your new loader to the MoltenVK ICD:
 
-    export VK_ICD_FILENAMES=<path to MoltenVK repository>/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json
+    export VK_DRIVER_FILES=<path to MoltenVK repository>/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json
 
 To run the loader test script, change to the `build/tests` directory in your
 Vulkan-Loader repository, and run:
index 7576822b953fa7850bbfef24e7d1087ca14c05b9..4999a06f1f68f2df4650403faa0175a0f8c0db57 100644 (file)
@@ -99,22 +99,37 @@ Driver.
 This could be for many reasons including using a beta driver, or forcing the
 loader to skip a problematic driver.
 In order to support this, the loader can be forced to look at specific
-drivers with the `VK_ICD_FILENAMES` environment variable.
+drivers with either the `VK_DRIVER_FILES` or the older `VK_ICD_FILENAMES`
+environment variable.
+Both these environment variables behave the same, but `VK_ICD_FILENAMES`
+should be considered deprecated.
 
-The `VK_ICD_FILENAMES` environment variable is a list of Driver Manifest
+The `VK_DRIVER_FILES` environment variable is a list of Driver Manifest
 files, containing the full path to the driver JSON Manifest file.
 This list is colon-separated on Linux and macOS, and semicolon-separated on
 Windows.
-Typically, `VK_ICD_FILENAMES` will only contain a full pathname to one info
+Typically, `VK_DRIVER_FILES` will only contain a full pathname to one info
 file for a single driver.
 A separator (colon or semicolon) is only used if more than one driver is needed.
 
+### Additional Driver Discovery
+
+There may be times that a developer wishes to force the loader to use a specific
+Driver in addition to the standard drivers (without replacing the standard
+search paths.
+The `VK_ADD_DRIVER_FILES` environment variable can be used to add a list of
+Driver Manifest files, containing the full path to the driver JSON Manifest file.
+This list is colon-separated on Linux and macOS, and semicolon-separated on
+Windows.
+It will be added prior to the standard driver search files.
+
 #### Exception for Elevated Privileges
 
-For security reasons, `VK_ICD_FILENAMES` is ignored if running the Vulkan
-application with elevated privileges.
-Because of this, `VK_ICD_FILENAMES` can only be used for applications that do not
-use elevated privileges.
+For security reasons, `VK_ICD_FILENAMES`, `VK_DRIVER_FILES` and
+`VK_ADD_DRIVER_FILES` are all ignored if running the Vulkan application with
+elevated privileges.
+Because of this, these environment variables can only be used for applications
+that do not use elevated privileges.
 
 For more information see
 [Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats)
@@ -132,28 +147,44 @@ For example:
 ##### On Windows
 
 ```
-set VK_ICD_FILENAMES=\windows\system32\nv-vk64.json
+set VK_DRIVER_FILES=\windows\system32\nv-vk64.json
 ```
 
-This is an example which is using the `VK_ICD_FILENAMES` override on Windows to
+This is an example which is using the `VK_DRIVER_FILES` override on Windows to
 point to the Nvidia Vulkan Driver's Manifest file.
 
+```
+set VK_ADD_DRIVER_FILES=\windows\system32\nv-vk64.json
+```
+
+This is an example which is using the `VK_ADD_DRIVER_FILES` on Windows to
+point to the Nvidia Vulkan Driver's Manifest file which will be loaded first
+before all other drivers.
+
 ##### On Linux
 
 ```
-export VK_ICD_FILENAMES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json
+export VK_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json
 ```
 
-This is an example which is using the `VK_ICD_FILENAMES` override on Linux to
+This is an example which is using the `VK_DRIVER_FILES` override on Linux to
 point to the Intel Mesa Driver's Manifest file.
 
+```
+export VK_ADD_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json
+```
+
+This is an example which is using the `VK_ADD_DRIVER_FILES` on Linux to
+point to the Intel Mesa Driver's Manifest file which will be loaded first
+before all other drivers.
+
 ##### On macOS
 
 ```
-export VK_ICD_FILENAMES=/home/user/MoltenVK/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json
+export VK_DRIVER_FILES=/home/user/MoltenVK/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json
 ```
 
-This is an example which is using the `VK_ICD_FILENAMES` override on macOS to
+This is an example which is using the `VK_DRIVER_FILES` override on macOS to
 point to an installation and build of the MoltenVK GitHub repository that
 contains the MoltenVK driver.
 
@@ -348,7 +379,7 @@ See the
 [Driver Manifest File Format](#driver-manifest-file-format)
 section for more details.
 
-It is also important to note that while `VK_LAYER_PATH` will point the loader
+It is also important to note that while `VK_DRIVER_FILES` will point the loader
 to finding the manifest files, it does not guarantee the library files mentioned
 by the manifest will immediately be found.
 Often, the Driver Manifest file will point to the library file using a
@@ -439,11 +470,11 @@ developer's build tree.
 In this case, there should be a way to allow developers to point to such an
 ICD without modifying the system-installed ICD(s) on their system.
 
-This need is met with the use of the `VK_ICD_FILENAMES` environment variable,
+This need is met with the use of the `VK_DRIVER_FILES` environment variable,
 which will override the mechanism used for finding system-installed
 drivers.
 
-In other words, only the drivers listed in `VK_ICD_FILENAMES` will be
+In other words, only the drivers listed in `VK_DRIVER_FILES` will be
 used.
 
 See
@@ -1614,8 +1645,9 @@ Android Vulkan documentation</a>.
   <tr>
     <td><small><b>LDP_LOADER_13</b></small></td>
     <td>A loader <b>must</b> not load from user-defined paths (including the
-        use of the <i>VK_ICD_FILENAMES</i> environment variable) when running
-        elevated (Administrator/Super-user) applications.<br/>
+        use of any of <i>VK_ICD_FILENAMES</i>, <i>VK_DRIVER_FILES</i>, or
+        <i>VK_ADD_DRIVER_FILES</i> environment variables) when running elevated
+        (Administrator/Super-user) applications.<br/>
         <b>This is for security reasons.</b>
     </td>
     <td>The behavior is undefined and may result in computer security lapses,
index 1db838df4fbc060a1df25904bc26b005c8d98f7d..73a50e40b93715e1075b097cc37a17214455f6cf 100644 (file)
@@ -417,8 +417,10 @@ using untrusted results.
 
 These behaviors also result in ignoring certain environment variables, such as:
 
-  * `VK_ICD_FILENAMES`
+  * `VK_DRIVER_FILES` / `VK_ICD_FILENAMES`
+  * `VK_ADD_DRIVER_FILES`
   * `VK_LAYER_PATH`
+  * `VK_ADD_LAYER_PATH`
   * `XDG_CONFIG_HOME` (Linux/Mac-specific)
   * `XDG_DATA_HOME` (Linux/Mac-specific)
 
@@ -491,8 +493,11 @@ discovery.
     <th>Example Format</th>
   </tr>
   <tr>
-    <td><small><i>VK_ICD_FILENAMES</i></small></td>
-    <td>Force the loader to use the specific ICD JSON files.
+    <td><small><i>VK_ADD_DRIVER_FILES</i></small></td>
+    <td>Provide a list of additional driver JSON files that the loader will use
+        in addition to the drivers that the loader would find normally.
+        The list of drivers will be added first, prior to the list of drivers
+        that would be found normally.
         The value contains a list of delimited full path listings to
         driver JSON Manifest files.<br/>
         <b>NOTE:</b> If a global path to the JSON file is not used, issues
@@ -503,11 +508,57 @@ discovery.
         for more information.
     </td>
     <td><small>export<br/>
-        &nbsp;&nbsp;VK_ICD_FILENAMES=<br/>
+        &nbsp;&nbsp;VK_ADD_DRIVER_FILES=<br/>
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<folder_a>/intel.json:<folder_b>/amd.json
         <br/> <br/>
         set<br/>
-        &nbsp;&nbsp;VK_ICD_FILENAMES=<br/>
+        &nbsp;&nbsp;VK_ADD_DRIVER_FILES=<br/>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<folder_a>\nvidia.json;<folder_b>\mesa.json
+        </small>
+    </td>
+  </tr>
+  <tr>
+    <td><small><i>VK_ADD_LAYER_PATH</i></small></td>
+    <td>Provide a list of additional paths that the loader will use to search
+        for layers in addition to the loader's standard Layer library search
+        folder when looking for explicit layer manifest files.
+        The paths will be added first, prior to the list of folders that would
+        be searched normally.
+        <br/>
+        <b>Ignored when running Vulkan application in executing with
+        elevated privileges.</b>
+        See <a href="#elevated-privilege-caveats">Elevated Privilege Caveats</a>
+        for more information.
+    </td>
+    <td><small>export<br/>
+        &nbsp;&nbsp;VK_ADD_LAYER_PATH=<br/>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;<br/><br/>
+        set<br/>
+        &nbsp;&nbsp;VK_ADD_LAYER_PATH=<br/>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;</small>
+    </td>
+  </tr>
+  <tr>
+    <td><small><i>VK_DRIVER_FILES</i></small></td>
+    <td>Force the loader to use the specific driver JSON files.
+        The value contains a list of delimited full path listings to
+        driver JSON Manifest files.<br/>
+        This has replaced the older deprecated environment variable
+        <i>VK_ICD_FILENAMES</i>, however the older environment variable will
+        continue to work for some time.
+        <b>NOTE:</b> If a global path to the JSON file is not used, issues
+        may be encountered.<br/>
+        <b>Ignored when running Vulkan application in executing with
+        elevated privileges.</b>
+        See <a href="#elevated-privilege-caveats">Elevated Privilege Caveats</a>
+        for more information.
+    </td>
+    <td><small>export<br/>
+        &nbsp;&nbsp;VK_DRIVER_FILES=<br/>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<folder_a>/intel.json:<folder_b>/amd.json
+        <br/> <br/>
+        set<br/>
+        &nbsp;&nbsp;VK_DRIVER_FILES=<br/>
         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<folder_a>\nvidia.json;<folder_b>\mesa.json
         </small>
     </td>
@@ -565,7 +616,6 @@ discovery.
         loader before returning the set of physical devices to layers.<br/>
     </td>
     <td><small>set VK_LOADER_DISABLE_SELECT=1</small>
-    </td>
   </tr>
   <tr>
     <td><small><i>VK_LOADER_DISABLE_INST_EXT_FILTER</i></small></td>
index 2f2a4097dd84a2777c81be53c4144810224f5e59..48b0ee1b8db40f7894c191411b7aa4fd90aa1fad 100644 (file)
@@ -231,8 +231,14 @@ If `VK_LAYER_PATH` is defined, then the loader will look at the paths defined by
 that variable for explicit layer manifest files instead of using the information
 provided by the explicit layer registry keys.
 
-For security reasons, `VK_LAYER_PATH` is ignored if running with elevated
-privileges.
+If `VK_ADD_LAYER_PATH` is defined, then the loader will look at the provided
+paths for explicit layer manifest files in addition to using the information
+provided by the explicit layer registry keys.
+The paths provided by `VK_ADD_LAYER_PATH` are added before the standard list
+of search folders and will therefore be searched first.
+
+For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
+if running with elevated privileges.
 See [Exception for Elevated Privileges](#exception-for-elevated-privileges)
 for more info.
 
@@ -317,10 +323,16 @@ manifest files:
 
 If `VK_LAYER_PATH` is defined, then the loader will look at the paths defined by
 that variable for explicit layer manifest files instead of using the information
-provided by the explicit layer paths.
+provided by the standard explicit layer paths mentioned above.
+
+If `VK_ADD_LAYER_PATH` is defined, then the loader will look at the provided
+paths for explicit layer manifest files in addition to using the information
+provided by the standard explicit layer paths mentioned above.
+The paths provided by `VK_ADD_LAYER_PATH` are added before the standard list
+of search folders and will therefore be searched first.
 
-For security reasons, `VK_LAYER_PATH` is ignored if running with elevated
-privileges.
+For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
+if running with elevated privileges.
 See [Exception for Elevated Privileges](#exception-for-elevated-privileges)
 for more info.
 
@@ -333,9 +345,10 @@ See
 in the [LoaderApplicationInterface.md document](LoaderApplicationInterface.md)
 for more information on this.
 
-It is also important to note that while `VK_LAYER_PATH` will point the loader
-to finding the manifest files, it does not guarantee the library files mentioned
-by the manifest will immediately be found.
+It is also important to note that while both `VK_LAYER_PATH` and
+`VK_ADD_LAYER_PATH` will point the loader paths to search for finding the
+manifest files, it does not guarantee the library files mentioned by the
+manifest will immediately be found.
 Often, the layer manifest file will point to the library file using a relative
 or absolute path.
 When a relative or absolute path is used, the loader can typically find the
@@ -397,11 +410,12 @@ following:
 
 ### Exception for Elevated Privileges
 
-There is an exception to when `VK_LAYER_PATH` is available for use.
-For security reasons, `VK_LAYER_PATH` is ignored if running the Vulkan
-application with elevated privileges.
-Because of this, `VK_LAYER_PATH` can only be used for applications that do not
-use elevated privileges.
+There is an exception to when either `VK_LAYER_PATH` or `VK_ADD_LAYER_PATH` are
+available for use.
+For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
+if running the Vulkan application with elevated privileges.
+Because of this, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` can only be used
+for applications that do not use elevated privileges.
 
 For more information see
 [Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats)
@@ -2409,8 +2423,9 @@ Android Vulkan documentation</a>.
   <tr>
     <td><small><b>LLP_LOADER_13</b></small></td>
     <td>A loader <b>must</b> not load from user-defined paths (including the
-        use of the <i>VK_LAYER_PATH</i> environment variable) when running
-        elevated (Administrator/Super-user) applications.<br/>
+        use of either <i>VK_LAYER_PATH</i> or <i>VK_ADD_LAYER_PATH</i>
+        environment variables) when running elevated (Administrator/Super-user)
+        applications.<br/>
         <b>This is for security reasons.</b>
     </td>
     <td>The behavior is undefined and may result in computer security lapses,
index 1adb03c8e52c1081c1260191ca688b9b40cd40cc..4452710ec2cf76f0420c4e1d79265c79a04a17b0 100644 (file)
@@ -119,6 +119,13 @@ int loader_closedir(const struct loader_instance *instance, DIR *dir) {
 #endif  // _WIN32
 }
 
+static bool is_json(const char *path, size_t len) {
+    if (len < 5) {
+        return false;
+    }
+    return !strncmp(path, ".json", 5);
+}
+
 // Handle error from to library loading
 void loader_handle_load_library_error(const struct loader_instance *inst, const char *filename,
                                       enum loader_layer_library_status *lib_status) {
@@ -2674,7 +2681,7 @@ static inline size_t determine_data_file_path_size(const char *cur_path, size_t
     return path_size;
 }
 
-static inline void copy_data_file_path(const char *cur_path, const char *relative_path, size_t relative_path_size,
+static inline void copy_data_file_info(const char *cur_path, const char *relative_path, size_t relative_path_size,
                                        char **output_path) {
     if (NULL != cur_path) {
         uint32_t start = 0;
@@ -2694,15 +2701,20 @@ static inline void copy_data_file_path(const char *cur_path, const char *relativ
                 memcpy(cur_write, &cur_path[start], s);
                 cur_write += s;
 
-                // If last symbol written was not a directory symbol, add it.
-                if (*(cur_write - 1) != DIRECTORY_SYMBOL) {
-                    *cur_write++ = DIRECTORY_SYMBOL;
+                // If this is a specific JSON file, just add it and don't add any
+                // relative path or directory symbol to it.
+                if (!is_json(cur_write - 5, s)) {
+                    // Add the relative directory if present.
+                    if (relative_path_size > 0) {
+                        // If last symbol written was not a directory symbol, add it.
+                        if (*(cur_write - 1) != DIRECTORY_SYMBOL) {
+                            *cur_write++ = DIRECTORY_SYMBOL;
+                        }
+                        memcpy(cur_write, relative_path, relative_path_size);
+                        cur_write += relative_path_size;
+                    }
                 }
 
-                if (relative_path_size > 0) {
-                    memcpy(cur_write, relative_path, relative_path_size);
-                    cur_write += relative_path_size;
-                }
                 *cur_write++ = PATH_SEPARATOR;
                 start = stop;
             }
@@ -2773,7 +2785,7 @@ static VkResult add_if_manifest_file(const struct loader_instance *inst, const c
     // Look for files ending with ".json" suffix
     size_t name_len = strlen(file_name);
     const char *name_suffix = file_name + name_len - 5;
-    if ((name_len < 5) || 0 != strncmp(name_suffix, ".json", 5)) {
+    if (!is_json(name_suffix, name_len)) {
         // Use incomplete to indicate invalid name, but to keep going.
         vk_result = VK_INCOMPLETE;
         goto out;
@@ -2786,8 +2798,10 @@ out:
     return vk_result;
 }
 
-VkResult add_data_files_in_path(const struct loader_instance *inst, char *search_path, bool is_directory_list,
-                                struct loader_data_files *out_files, bool use_first_found_manifest) {
+// Add any files found in the search_path.  If any path in the search path points to a specific JSON, attempt to
+// only open that one JSON.  Otherwise, if the path is a folder, search the folder for JSON files.
+VkResult add_data_files(const struct loader_instance *inst, char *search_path, struct loader_data_files *out_files,
+                        bool use_first_found_manifest) {
     VkResult vk_result = VK_SUCCESS;
     DIR *dir_stream = NULL;
     struct dirent *dir_entry;
@@ -2806,38 +2820,9 @@ VkResult add_data_files_in_path(const struct loader_instance *inst, char *search
         cur_file = next_file;
         next_file = loader_get_next_path(cur_file);
 
-        // Get the next name in the list and verify it's valid
-        if (is_directory_list) {
-            dir_stream = loader_opendir(inst, cur_file);
-            if (NULL == dir_stream) {
-                continue;
-            }
-            while (1) {
-                dir_entry = readdir(dir_stream);
-                if (NULL == dir_entry) {
-                    break;
-                }
-
-                name = &(dir_entry->d_name[0]);
-                loader_get_fullpath(name, cur_file, sizeof(full_path), full_path);
-                name = full_path;
-
-                VkResult local_res;
-                local_res = add_if_manifest_file(inst, name, out_files);
-
-                // Incomplete means this was not a valid data file.
-                if (local_res == VK_INCOMPLETE) {
-                    continue;
-                } else if (local_res != VK_SUCCESS) {
-                    vk_result = local_res;
-                    break;
-                }
-            }
-            loader_closedir(inst, dir_stream);
-            if (vk_result != VK_SUCCESS) {
-                goto out;
-            }
-        } else {
+        // Is this a JSON file, then try to open it.
+        size_t len = strlen(cur_file);
+        if (is_json(cur_file + len - 5, len)) {
 #ifdef _WIN32
             name = cur_file;
 #else
@@ -2849,7 +2834,7 @@ VkResult add_data_files_in_path(const struct loader_instance *inst, char *search
                 str_len = strlen(cur_file) + 1;
             }
             if (str_len > sizeof(temp_path)) {
-                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "add_data_files_in_path: Path to %s too long\n", cur_file);
+                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "add_data_files: Path to %s too long\n", cur_file);
                 continue;
             }
             strcpy(temp_path, cur_file);
@@ -2868,6 +2853,36 @@ VkResult add_data_files_in_path(const struct loader_instance *inst, char *search
                 vk_result = local_res;
                 break;
             }
+        } else {  // Otherwise, treat it as a directory
+            dir_stream = loader_opendir(inst, cur_file);
+            if (NULL == dir_stream) {
+                continue;
+            }
+            while (1) {
+                dir_entry = readdir(dir_stream);
+                if (NULL == dir_entry) {
+                    break;
+                }
+
+                name = &(dir_entry->d_name[0]);
+                loader_get_fullpath(name, cur_file, sizeof(full_path), full_path);
+                name = full_path;
+
+                VkResult local_res;
+                local_res = add_if_manifest_file(inst, name, out_files);
+
+                // Incomplete means this was not a valid data file.
+                if (local_res == VK_INCOMPLETE) {
+                    continue;
+                } else if (local_res != VK_SUCCESS) {
+                    vk_result = local_res;
+                    break;
+                }
+            }
+            loader_closedir(inst, dir_stream);
+            if (vk_result != VK_SUCCESS) {
+                goto out;
+            }
         }
         if (use_first_found_manifest && out_files->count > 0) {
             break;
@@ -2881,14 +2896,15 @@ out:
 
 // Look for data files in the provided paths, but first check the environment override to determine if we should use that
 // instead.
-static VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
-                                                const char *env_override, const char *path_override, const char *relative_location,
-                                                bool *override_active, struct loader_data_files *out_files) {
+static VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enum loader_json_type json_type,
+                                                const char *path_override, bool *override_active,
+                                                struct loader_data_files *out_files) {
     VkResult vk_result = VK_SUCCESS;
-    bool is_directory_list = true;
-    bool is_icd = (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD);
+    bool is_icd = false;
     char *override_env = NULL;
     const char *override_path = NULL;
+    char *relative_location = NULL;
+    char *additional_env = NULL;
     size_t search_path_size = 0;
     char *search_path = NULL;
     char *cur_path_ptr = NULL;
@@ -2937,6 +2953,8 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
     char *home = NULL;
     char *default_data_home = NULL;
     char *default_config_home = NULL;
+    char *home_data_dir = NULL;
+    char *home_config_dir = NULL;
 
     // Only use HOME if XDG_DATA_HOME is not present on the system
     home = loader_secure_getenv("HOME", inst);
@@ -2964,17 +2982,43 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
             strcat(default_data_home, data_suffix);
         }
     }
+
+    if (NULL != default_config_home) {
+        home_config_dir = default_config_home;
+    } else {
+        home_config_dir = xdg_config_home;
+    }
+    if (NULL != default_data_home) {
+        home_data_dir = default_data_home;
+    } else {
+        home_data_dir = xdg_data_home;
+    }
 #endif  // !_WIN32
 
+    switch (json_type) {
+        case VULKAN_LOADER_JSON_DRIVER:
+            is_icd = true;
+            override_env = loader_secure_getenv(VK_DRIVER_FILES_ENV_VAR, inst);
+            if (NULL == override_env) {
+                // Not there, so fall back to the old name
+                override_env = loader_secure_getenv(VK_ICD_FILENAMES_ENV_VAR, inst);
+            }
+            additional_env = loader_secure_getenv(VK_ADDITIONAL_DRIVER_FILES_ENV_VAR, inst);
+            relative_location = VK_DRIVERS_INFO_RELATIVE_DIR;
+            break;
+        case VULKAN_LOADER_JSON_IMPLICIT_LAYER:
+            relative_location = VK_ILAYERS_INFO_RELATIVE_DIR;
+            break;
+        case VULKAN_LOADER_JSON_EXPLICIT_LAYER:
+            override_env = loader_secure_getenv(VK_LAYER_PATH_ENV_VAR, inst);
+            additional_env = loader_secure_getenv(VK_ADDITIONAL_LAYER_PATH_ENV_VAR, inst);
+            relative_location = VK_ELAYERS_INFO_RELATIVE_DIR;
+            break;
+    }
+
     if (path_override != NULL) {
         override_path = path_override;
-    } else if (env_override != NULL) {
-        override_env = loader_secure_getenv(env_override, inst);
-
-        // The ICD override is actually a specific list of filenames, not directories
-        if (is_icd && NULL != override_env) {
-            is_directory_list = false;
-        }
+    } else if (override_env != NULL) {
         override_path = override_env;
     }
 
@@ -2984,45 +3028,49 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
     // If there's an override, use that (and the local folder if required) and nothing else
     if (NULL != override_path) {
         // Local folder and null terminator
-        search_path_size += strlen(override_path) + 1;
+        search_path_size += strlen(override_path) + 2;
+
+        // Add the size of any additional search paths defined in the additive environment variable
+        if (NULL != additional_env) {
+            search_path_size += determine_data_file_path_size(additional_env, 0) + 2;
+        }
     } else if (NULL == relative_location) {
         // If there's no override, and no relative location, bail out.  This is usually
         // the case when we're on Windows and the default path is to use the registry.
         goto out;
     } else {
+        // Add the size of any additional search paths defined in the additive environment variable
+        if (NULL != additional_env) {
+            search_path_size += determine_data_file_path_size(additional_env, 0) + 2;
+#ifdef _WIN32
+        } else {
+            goto out;
+        }
+#else  // !_WIN32
+        }
+
         // Add the general search folders (with the appropriate relative folder added)
         rel_size = strlen(relative_location);
-        if (rel_size == 0) {
-            goto out;
-        } else {
+        if (rel_size > 0) {
 #if defined(__APPLE__)
             search_path_size += MAXPATHLEN;
 #endif
-#ifndef _WIN32
-            // Only add the home folders if not ICD filenames or superuser
-            if (is_directory_list && !is_high_integrity()) {
-                if (NULL != default_config_home) {
-                    search_path_size += determine_data_file_path_size(default_config_home, rel_size);
-                } else {
-                    search_path_size += determine_data_file_path_size(xdg_config_home, rel_size);
-                }
+            // Only add the home folders if defined
+            if (NULL != home_config_dir) {
+                search_path_size += determine_data_file_path_size(home_config_dir, rel_size);
             }
             search_path_size += determine_data_file_path_size(xdg_config_dirs, rel_size);
             search_path_size += determine_data_file_path_size(SYSCONFDIR, rel_size);
 #if defined(EXTRASYSCONFDIR)
             search_path_size += determine_data_file_path_size(EXTRASYSCONFDIR, rel_size);
 #endif
-            // Only add the home folders if not ICD filenames or superuser
-            if (is_directory_list && !is_high_integrity()) {
-                if (NULL != default_data_home) {
-                    search_path_size += determine_data_file_path_size(default_data_home, rel_size);
-                } else {
-                    search_path_size += determine_data_file_path_size(xdg_data_home, rel_size);
-                }
+            // Only add the home folders if defined
+            if (NULL != home_data_dir) {
+                search_path_size += determine_data_file_path_size(home_data_dir, rel_size);
             }
             search_path_size += determine_data_file_path_size(xdg_data_dirs, rel_size);
-#endif  // !_WIN32
         }
+#endif  // !_WIN32
     }
 
     // Allocate the required space
@@ -3040,7 +3088,22 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
     // Add the remaining paths to the list
     if (NULL != override_path) {
         strcpy(cur_path_ptr, override_path);
+        cur_path_ptr += strlen(override_path);
+        if (NULL != additional_env) {
+            *cur_path_ptr++ = PATH_SEPARATOR;
+
+            copy_data_file_info(additional_env, NULL, 0, &cur_path_ptr);
+
+            // Remove the last path separator
+            --cur_path_ptr;
+            *cur_path_ptr = '\0';
+        }
     } else {
+        // Add any additional search paths defined in the additive environment variable
+        if (NULL != additional_env) {
+            copy_data_file_info(additional_env, NULL, 0, &cur_path_ptr);
+        }
+
 #ifndef _WIN32
         if (rel_size > 0) {
 #if defined(__APPLE__)
@@ -3057,7 +3120,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
                         cur_path_ptr += rel_size;
                         *cur_path_ptr++ = PATH_SEPARATOR;
                         // only for ICD manifests
-                        if (env_override != NULL && strcmp(VK_ICD_FILENAMES_ENV_VAR, env_override) == 0) {
+                        if (override_env != NULL && is_icd) {
                             use_first_found_manifest = true;
                         }
                     }
@@ -3065,29 +3128,22 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
                 }
             }
 #endif  // __APPLE__
-        // Only add the home folders if not ICD filenames or superuser
-            if (is_directory_list && !is_high_integrity()) {
-                if (NULL != default_config_home) {
-                    copy_data_file_path(default_config_home, relative_location, rel_size, &cur_path_ptr);
-                } else {
-                    copy_data_file_path(xdg_config_home, relative_location, rel_size, &cur_path_ptr);
-                }
+
+            // Only add the home folders if not NULL
+            if (NULL != home_config_dir) {
+                copy_data_file_info(home_config_dir, relative_location, rel_size, &cur_path_ptr);
             }
-            copy_data_file_path(xdg_config_dirs, relative_location, rel_size, &cur_path_ptr);
-            copy_data_file_path(SYSCONFDIR, relative_location, rel_size, &cur_path_ptr);
+            copy_data_file_info(xdg_config_dirs, relative_location, rel_size, &cur_path_ptr);
+            copy_data_file_info(SYSCONFDIR, relative_location, rel_size, &cur_path_ptr);
 #if defined(EXTRASYSCONFDIR)
-            copy_data_file_path(EXTRASYSCONFDIR, relative_location, rel_size, &cur_path_ptr);
+            copy_data_file_info(EXTRASYSCONFDIR, relative_location, rel_size, &cur_path_ptr);
 #endif
 
-            // Only add the home folders if not ICD filenames or superuser
-            if (is_directory_list && !is_high_integrity()) {
-                if (NULL != default_data_home) {
-                    copy_data_file_path(default_data_home, relative_location, rel_size, &cur_path_ptr);
-                } else {
-                    copy_data_file_path(xdg_data_home, relative_location, rel_size, &cur_path_ptr);
-                }
+            // Only add the home folders if not NULL
+            if (NULL != home_data_dir) {
+                copy_data_file_info(home_data_dir, relative_location, rel_size, &cur_path_ptr);
             }
-            copy_data_file_path(xdg_data_dirs, relative_location, rel_size, &cur_path_ptr);
+            copy_data_file_info(xdg_data_dirs, relative_location, rel_size, &cur_path_ptr);
         }
 
         // Remove the last path separator
@@ -3138,7 +3194,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
         if (NULL != tmp_search_path) {
             strncpy(tmp_search_path, search_path, search_path_size);
             tmp_search_path[search_path_size] = '\0';
-            if (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD) {
+            if (is_icd) {
                 log_flags = VULKAN_LOADER_DRIVER_BIT;
                 loader_log(inst, VULKAN_LOADER_DRIVER_BIT, 0, "Searching for driver manifest files");
             } else {
@@ -3158,7 +3214,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
     }
 
     // Now, parse the paths and add any manifest files found in them.
-    vk_result = add_data_files_in_path(inst, search_path, is_directory_list, out_files, use_first_found_manifest);
+    vk_result = add_data_files(inst, search_path, out_files, use_first_found_manifest);
 
     if (log_flags != 0 && out_files->count > 0) {
         loader_log(inst, log_flags, 0, "   Found the following files:");
@@ -3177,6 +3233,9 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
 
 out:
 
+    if (NULL != additional_env) {
+        loader_free_getenv(additional_env, inst);
+    }
     if (NULL != override_env) {
         loader_free_getenv(override_env, inst);
     }
@@ -3216,15 +3275,12 @@ out:
 
 // Find the Vulkan library manifest files.
 //
-// This function scans the "location" or "env_override" directories/files
-// for a list of JSON manifest files.  If env_override is non-NULL
-// and has a valid value. Then the location is ignored.  Otherwise
-// location is used to look for manifest files. The location
-// is interpreted as  Registry path on Windows and a directory path(s)
-// on Linux. "home_location" is an additional directory in the users home
-// directory to look at. It is expanded into the dir path
-// $XDG_DATA_HOME/home_location or $HOME/.local/share/home_location depending
-// on environment variables. This "home_location" is only used on Linux.
+// This function scans the appropriate locations for a list of JSON manifest files based on the
+// "json_type".  The location is interpreted as Registry path on Windows and a directory path(s)
+// on Linux.
+// "home_location" is an additional directory in the users home directory to look at. It is
+// expanded into the dir path $XDG_DATA_HOME/home_location or $HOME/.local/share/home_location
+// depending on environment variables. This "home_location" is only used on Linux.
 //
 // \returns
 // VKResult
@@ -3239,9 +3295,9 @@ out:
 // Win Layer  | files    | dirs
 // Linux ICD  | dirs     | files
 // Linux Layer| dirs     | dirs
-VkResult loader_get_data_files(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
-                               bool warn_if_not_present, const char *env_override, const char *path_override,
-                               char *registry_location, const char *relative_location, struct loader_data_files *out_files) {
+
+VkResult loader_get_data_files(const struct loader_instance *inst, enum loader_json_type json_type, const char *path_override,
+                               struct loader_data_files *out_files) {
     VkResult res = VK_SUCCESS;
     bool override_active = false;
 
@@ -3259,8 +3315,7 @@ VkResult loader_get_data_files(const struct loader_instance *inst, enum loader_d
     out_files->alloc_count = 0;
     out_files->filename_list = NULL;
 
-    res = read_data_files_in_search_paths(inst, data_file_type, env_override, path_override, relative_location, &override_active,
-                                          out_files);
+    res = read_data_files_in_search_paths(inst, json_type, path_override, &override_active, out_files);
     if (VK_SUCCESS != res) {
         goto out;
     }
@@ -3268,8 +3323,32 @@ VkResult loader_get_data_files(const struct loader_instance *inst, enum loader_d
 #ifdef _WIN32
     // Read the registry if the override wasn't active.
     if (!override_active) {
-        res = windows_read_data_files_in_registry(inst, data_file_type, warn_if_not_present, registry_location, out_files);
-        if (VK_SUCCESS != res) {
+        bool warn_if_not_present = false;
+        char *registry_location = NULL;
+        enum loader_data_files_type manifest_type = LOADER_DATA_FILE_MANIFEST_DRIVER;
+
+        switch (json_type) {
+            default:
+                goto out;
+            case VULKAN_LOADER_JSON_DRIVER:
+                warn_if_not_present = true;
+                registry_location = VK_DRIVERS_INFO_REGISTRY_LOC;
+                break;
+            case VULKAN_LOADER_JSON_IMPLICIT_LAYER:
+                manifest_type = LOADER_DATA_FILE_MANIFEST_LAYER;
+                registry_location = VK_ILAYERS_INFO_REGISTRY_LOC;
+                break;
+            case VULKAN_LOADER_JSON_EXPLICIT_LAYER:
+                warn_if_not_present = true;
+                manifest_type = LOADER_DATA_FILE_MANIFEST_LAYER;
+                registry_location = VK_ELAYERS_INFO_REGISTRY_LOC;
+                break;
+        }
+        VkResult tmp_res =
+            windows_read_data_files_in_registry(inst, manifest_type, warn_if_not_present, registry_location, out_files);
+        // Only return an error if there was an error this time, and no manifest files from before.
+        if (VK_SUCCESS != tmp_res && out_files->count == 0) {
+            res = tmp_res;
             goto out;
         }
     }
@@ -3296,10 +3375,10 @@ void loader_destroy_icd_lib_list() {}
 
 // Try to find the Vulkan ICD driver(s).
 //
-// This function scans the default system loader path(s) or path
-// specified by the \c VK_ICD_FILENAMES environment variable in
-// order to find loadable VK ICDs manifest files. From these
-// manifest files it finds the ICD libraries.
+// This function scans the default system loader path(s) or path specified by either the
+// VK_DRIVER_FILES or VK_ICD_FILENAMES environment variable in order to find loadable
+// VK ICDs manifest files.
+// From these manifest files it finds the ICD libraries.
 //
 // \returns
 // Vulkan result
@@ -3320,8 +3399,7 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
         goto out;
     }
     // Get a list of manifest files for ICDs
-    res = loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_ICD, true, VK_ICD_FILENAMES_ENV_VAR, NULL,
-                                VK_DRIVERS_INFO_REGISTRY_LOC, VK_DRIVERS_INFO_RELATIVE_DIR, &manifest_files);
+    res = loader_get_data_files(inst, VULKAN_LOADER_JSON_DRIVER, NULL, &manifest_files);
     if (VK_SUCCESS != res || manifest_files.count == 0) {
         goto out;
     }
@@ -3568,9 +3646,7 @@ void loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_li
     loader_platform_thread_lock_mutex(&loader_json_lock);
 
     // 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_data_files(inst, LOADER_DATA_FILE_MANIFEST_LAYER, false, NULL, NULL, VK_ILAYERS_INFO_REGISTRY_LOC,
-                                            VK_ILAYERS_INFO_RELATIVE_DIR, &manifest_files)) {
+    if (VK_SUCCESS != loader_get_data_files(inst, VULKAN_LOADER_JSON_IMPLICIT_LAYER, NULL, &manifest_files)) {
         goto out;
     }
 
@@ -3618,7 +3694,7 @@ void loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_li
             }
             cur_write_ptr = &override_paths[0];
             for (uint32_t j = 0; j < prop->num_override_paths; j++) {
-                copy_data_file_path(prop->override_paths[j], NULL, 0, &cur_write_ptr);
+                copy_data_file_info(prop->override_paths[j], NULL, 0, &cur_write_ptr);
             }
             // Remove the last path separator
             --cur_write_ptr;
@@ -3630,8 +3706,7 @@ void loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_li
     }
 
     // Get a list of manifest files for explicit layers
-    if (VK_SUCCESS != loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_LAYER, true, VK_LAYER_PATH_ENV_VAR, override_paths,
-                                            VK_ELAYERS_INFO_REGISTRY_LOC, VK_ELAYERS_INFO_RELATIVE_DIR, &manifest_files)) {
+    if (VK_SUCCESS != loader_get_data_files(inst, VULKAN_LOADER_JSON_EXPLICIT_LAYER, override_paths, &manifest_files)) {
         goto out;
     }
 
@@ -3703,9 +3778,7 @@ void loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader
     // a failure occurs before allocating the manifest filename_list.
     memset(&manifest_files, 0, sizeof(struct loader_data_files));
 
-    // Pass NULL for environment variable override - implicit layers are not overridden by LAYERS_PATH_ENV
-    VkResult res = loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_LAYER, false, NULL, NULL, VK_ILAYERS_INFO_REGISTRY_LOC,
-                                         VK_ILAYERS_INFO_RELATIVE_DIR, &manifest_files);
+    VkResult res = loader_get_data_files(inst, VULKAN_LOADER_JSON_IMPLICIT_LAYER, NULL, &manifest_files);
     if (VK_SUCCESS != res || manifest_files.count == 0) {
         goto out;
     }
@@ -3762,7 +3835,7 @@ void loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader
                 }
                 cur_write_ptr = &override_paths[0];
                 for (uint32_t j = 0; j < prop->num_override_paths; j++) {
-                    copy_data_file_path(prop->override_paths[j], NULL, 0, &cur_write_ptr);
+                    copy_data_file_info(prop->override_paths[j], NULL, 0, &cur_write_ptr);
                 }
                 // Remove the last path separator
                 --cur_write_ptr;
@@ -3780,8 +3853,7 @@ void loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader
     // explicit layer info as well.  Not to worry, though, all explicit layers not included
     // in the override layer will be removed below in loader_remove_layers_in_blacklist().
     if (override_layer_valid || implicit_metalayer_present) {
-        if (VK_SUCCESS != loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_LAYER, true, VK_LAYER_PATH_ENV_VAR, override_paths,
-                                                VK_ELAYERS_INFO_REGISTRY_LOC, VK_ELAYERS_INFO_RELATIVE_DIR, &manifest_files)) {
+        if (VK_SUCCESS != loader_get_data_files(inst, VULKAN_LOADER_JSON_EXPLICIT_LAYER, override_paths, &manifest_files)) {
             goto out;
         }
 
@@ -5695,6 +5767,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI
     // If no ICDs were added to instance list and res is unchanged from it's initial value, the loader was unable to
     // find a suitable ICD.
     if (VK_SUCCESS == res && (ptr_instance->icd_terms == NULL || !one_icd_successful)) {
+        loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+                   "terminator_CreateInstance: Found no drivers!");
         res = VK_ERROR_INCOMPATIBLE_DRIVER;
     }
 
index 4ef699664fe6604bcc1fb9e9f455ce2072bcd256..51c5aae968b0471d9fae366344719488ad607459 100644 (file)
@@ -169,5 +169,5 @@ VkResult setup_loader_tramp_phys_dev_groups(struct loader_instance *inst, uint32
 
 VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
 char *loader_get_next_path(char *path);
-VkResult add_data_files_in_path(const struct loader_instance *inst, char *search_path, bool is_directory_list,
-                                struct loader_data_files *out_files, bool use_first_found_manifest);
\ No newline at end of file
+VkResult add_data_files(const struct loader_instance *inst, char *search_path, struct loader_data_files *out_files,
+                        bool use_first_found_manifest);
index 3b8c7c00df62262a1e9150d66b2189d227f569b2..e00393885e47b2ea84b4fde3f6fae9bd337a4539 100644 (file)
 
 #include "vk_loader_platform.h"
 
+enum loader_json_type {
+    VULKAN_LOADER_JSON_DRIVER = 0,
+    VULKAN_LOADER_JSON_IMPLICIT_LAYER,
+    VULKAN_LOADER_JSON_EXPLICIT_LAYER,
+};
+
 enum layer_type_flags {
     VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1,  // If not set, indicates Device layer
     VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2,  // If not set, indicates Implicit layer
@@ -445,7 +451,7 @@ struct loader_scanned_icd {
 };
 
 enum loader_data_files_type {
-    LOADER_DATA_FILE_MANIFEST_ICD = 0,
+    LOADER_DATA_FILE_MANIFEST_DRIVER = 0,
     LOADER_DATA_FILE_MANIFEST_LAYER,
     LOADER_DATA_FILE_NUM_TYPES  // Not a real field, used for possible loop terminator
 };
index a16019bd65805f712e63eec605b4bf4ea0d03eac..7aa730e460b9fa19b029f3ce6132b8501666c388 100644 (file)
@@ -168,7 +168,7 @@ bool windows_get_device_registry_entry(const struct loader_instance *inst, char
 
     CONFIGRET status = CM_Open_DevNode_Key(dev_id, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkrKey, CM_REGISTRY_SOFTWARE);
     if (status != CR_SUCCESS) {
-        loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
+        loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                    "windows_get_device_registry_entry: Failed to open registry key for DeviceID(%d)", dev_id);
         *result = VK_ERROR_INCOMPATIBLE_DRIVER;
         return false;
@@ -179,18 +179,19 @@ bool windows_get_device_registry_entry(const struct loader_instance *inst, char
 
     if (ret != ERROR_SUCCESS) {
         if (ret == ERROR_FILE_NOT_FOUND) {
-            loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+            loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                        "windows_get_device_registry_entry: Device ID(%d) Does not contain a value for \"%s\"", dev_id, value_name);
         } else {
-            loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s size",
-                       dev_id, value_name);
+            loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+                       "windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s size", dev_id, value_name);
         }
         goto out;
     }
 
     manifest_path = loader_instance_heap_alloc(inst, requiredSize, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (manifest_path == NULL) {
-        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "windows_get_device_registry_entry: Failed to allocate space for DriverName.");
+        loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+                   "windows_get_device_registry_entry: Failed to allocate space for DriverName.");
         *result = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
     }
@@ -198,14 +199,14 @@ bool windows_get_device_registry_entry(const struct loader_instance *inst, char
     ret = RegQueryValueEx(hkrKey, value_name, NULL, &data_type, (BYTE *)manifest_path, &requiredSize);
 
     if (ret != ERROR_SUCCESS) {
-        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s",
-                   value_name);
+        loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+                   "windows_get_device_registry_entry: DeviceID(%d) Failed to obtain %s", value_name);
         *result = VK_ERROR_INCOMPATIBLE_DRIVER;
         goto out;
     }
 
     if (data_type != REG_SZ && data_type != REG_MULTI_SZ) {
-        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+        loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
                    "windows_get_device_registry_entry: Invalid %s data type. Expected REG_SZ or REG_MULTI_SZ.", value_name);
         *result = VK_ERROR_INCOMPATIBLE_DRIVER;
         goto out;
@@ -221,8 +222,8 @@ out:
     return found;
 }
 
-VkResult windows_get_device_registry_files(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size,
-                                           LPCSTR value_name) {
+VkResult windows_get_device_registry_files(const struct loader_instance *inst, uint32_t log_target_flag, char **reg_data,
+                                           PDWORD reg_data_size, LPCSTR value_name) {
     static const wchar_t *softwareComponentGUID = L"{5c4c3332-344d-483c-8739-259e934c9cc8}";
     static const wchar_t *displayGUID = L"{4d36e968-e325-11ce-bfc1-08002be10318}";
 #ifdef CM_GETIDLIST_FILTER_PRESENT
@@ -252,7 +253,7 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, c
 
         pDeviceNames = loader_instance_heap_alloc(inst, deviceNamesSize * sizeof(wchar_t), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (pDeviceNames == NULL) {
-            loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+            loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                        "windows_get_device_registry_files: Failed to allocate space for display device names.");
             result = VK_ERROR_OUT_OF_HOST_MEMORY;
             return result;
@@ -263,25 +264,26 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, c
         for (wchar_t *deviceName = pDeviceNames; *deviceName; deviceName += wcslen(deviceName) + 1) {
             CONFIGRET status = CM_Locate_DevNodeW(&devID, deviceName, CM_LOCATE_DEVNODE_NORMAL);
             if (CR_SUCCESS != status) {
-                loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "windows_get_device_registry_files: failed to open DevNode %ls",
-                           deviceName);
+                loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
+                           "windows_get_device_registry_files: failed to open DevNode %ls", deviceName);
                 continue;
             }
             ULONG ulStatus, ulProblem;
             status = CM_Get_DevNode_Status(&ulStatus, &ulProblem, devID, 0);
 
             if (CR_SUCCESS != status) {
-                loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "windows_get_device_registry_files: failed to probe device status %ls",
-                           deviceName);
+                loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
+                           "windows_get_device_registry_files: failed to probe device status %ls", deviceName);
                 continue;
             }
             if ((ulStatus & DN_HAS_PROBLEM) && (ulProblem == CM_PROB_NEED_RESTART || ulProblem == DN_NEED_RESTART)) {
-                loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                            "windows_get_device_registry_files: device %ls is pending reboot, skipping ...", deviceName);
                 continue;
             }
 
-            loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "windows_get_device_registry_files: opening device %ls", deviceName);
+            loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0, "windows_get_device_registry_files: opening device %ls",
+                       deviceName);
 
             if (windows_get_device_registry_entry(inst, reg_data, reg_data_size, devID, value_name, &result)) {
                 found = true;
@@ -292,7 +294,7 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, c
 
             status = CM_Get_Child(&childID, devID, 0);
             if (status != CR_SUCCESS) {
-                loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                            "windows_get_device_registry_files: unable to open child-device error:%d", status);
                 continue;
             }
@@ -301,12 +303,12 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, c
                 wchar_t buffer[MAX_DEVICE_ID_LEN];
                 CM_Get_Device_IDW(childID, buffer, MAX_DEVICE_ID_LEN, 0);
 
-                loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "windows_get_device_registry_files: Opening child device %d - %ls",
-                           childID, buffer);
+                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
+                           "windows_get_device_registry_files: Opening child device %d - %ls", childID, buffer);
 
                 status = CM_Get_DevNode_Registry_PropertyW(childID, CM_DRP_CLASSGUID, NULL, &childGuid, &childGuidSize, 0);
                 if (status != CR_SUCCESS) {
-                    loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+                    loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                                "windows_get_device_registry_files: unable to obtain GUID for:%d error:%d", childID, status);
 
                     result = VK_ERROR_INCOMPATIBLE_DRIVER;
@@ -314,7 +316,7 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, c
                 }
 
                 if (wcscmp(childGuid, softwareComponentGUID) != 0) {
-                    loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
+                    loader_log(inst, VULKAN_LOADER_DEBUG_BIT | log_target_flag, 0,
                                "windows_get_device_registry_files: GUID for %d is not SoftwareComponent skipping", childID);
                     continue;
                 }
@@ -331,6 +333,7 @@ VkResult windows_get_device_registry_files(const struct loader_instance *inst, c
     }
 
     if (!found && result != VK_ERROR_OUT_OF_HOST_MEMORY) {
+        loader_log(inst, log_target_flag, 0, "windows_get_device_registry_files: found no registry files");
         result = VK_ERROR_INCOMPATIBLE_DRIVER;
     }
 
@@ -395,13 +398,14 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
     bool found = false;
     IDXGIFactory1 *dxgi_factory = NULL;
     bool is_driver = !strcmp(location, VK_DRIVERS_INFO_REGISTRY_LOC);
+    uint32_t log_target_flag = is_driver ? VULKAN_LOADER_DRIVER_BIT : VULKAN_LOADER_LAYER_BIT;
 
     assert(reg_data != NULL && "windows_get_registry_files: reg_data is a NULL pointer");
 
     if (is_driver) {
         HRESULT hres = fpCreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&dxgi_factory);
         if (hres != S_OK) {
-            loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
+            loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                        "windows_get_registry_files: Failed to create dxgi factory for ICD registry verification. No ICDs will be "
                        "added from "
                        "legacy registry locations");
@@ -421,7 +425,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
                     if (NULL == *reg_data) {
                         *reg_data = loader_instance_heap_alloc(inst, *reg_data_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
                         if (NULL == *reg_data) {
-                            loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+                            loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                                        "windows_get_registry_files: Failed to allocate space for registry data for key %s", name);
                             RegCloseKey(key);
                             result = VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -433,7 +437,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
                                                                      VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
                         if (NULL == new_ptr) {
                             loader_log(
-                                inst, VULKAN_LOADER_ERROR_BIT, 0,
+                                inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                                 "windows_get_registry_files: Failed to reallocate space for registry value of size %d for key %s",
                                 *reg_data_size * 2, name);
                             RegCloseKey(key);
@@ -446,7 +450,8 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
 
                     // We've now found a json file. If this is an ICD, we still need to check if there is actually a device
                     // that matches this ICD
-                    loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Located json file \"%s\" from registry \"%s\\%s\"", name,
+                    loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
+                               "Located json file \"%s\" from registry \"%s\\%s\"", name,
                                hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR,
                                location);
                     if (is_driver) {
@@ -457,7 +462,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
                             }
                         }
                         if (i == sizeof(known_drivers) / sizeof(known_drivers[0])) {
-                            loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                            loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                        "Driver %s is not recognized as a known driver. It will be assumed to be active", name);
                         } else {
                             bool found_gpu = false;
@@ -467,7 +472,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
                                 if (hres == DXGI_ERROR_NOT_FOUND) {
                                     break;
                                 } else if (hres != S_OK) {
-                                    loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
+                                    loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                                                "Failed to enumerate DXGI adapters at index %d. As a result, drivers may be skipped",
                                                j);
                                     continue;
@@ -477,7 +482,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
                                 hres = adapter->lpVtbl->GetDesc1(adapter, &description);
                                 if (hres != S_OK) {
                                     loader_log(
-                                        inst, VULKAN_LOADER_INFO_BIT, 0,
+                                        inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                         "Failed to get DXGI adapter information at index %d. As a result, drivers may be skipped",
                                         j);
                                     continue;
@@ -490,7 +495,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
                             }
 
                             if (!found_gpu) {
-                                loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                                loader_log(inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                            "Dropping driver %s as no corresponding DXGI adapter was found", name);
                                 continue;
                             }
@@ -523,7 +528,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
                             found = true;
                         } else {
                             loader_log(
-                                inst, VULKAN_LOADER_INFO_BIT, 0,
+                                inst, VULKAN_LOADER_INFO_BIT | log_target_flag, 0,
                                 "Skipping adding of json file \"%s\" from registry \"%s\\%s\" to the list due to duplication", name,
                                 hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR,
                                 location);
@@ -544,6 +549,7 @@ VkResult windows_get_registry_files(const struct loader_instance *inst, char *lo
     }
 
     if (!found && result != VK_ERROR_OUT_OF_HOST_MEMORY) {
+        loader_log(inst, log_target_flag, 0, "Found no registry files in %s", location);
         result = VK_ERROR_INCOMPATIBLE_DRIVER;
     }
 
@@ -693,11 +699,14 @@ VkResult windows_read_data_files_in_registry(const struct loader_instance *inst,
                                              struct loader_data_files *out_files) {
     VkResult vk_result = VK_SUCCESS;
     char *search_path = NULL;
+    uint32_t log_target_flag = 0;
 
-    if (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD) {
-        loader_log(inst, VULKAN_LOADER_DRIVER_BIT, 0, "Checking for Driver Manifest files in Registry at %s", registry_location);
+    if (data_file_type == LOADER_DATA_FILE_MANIFEST_DRIVER) {
+        log_target_flag = VULKAN_LOADER_DRIVER_BIT;
+        loader_log(inst, log_target_flag, 0, "Checking for Driver Manifest files in Registry at %s", registry_location);
     } else {
-        loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, "Checking for Driver Manifest files in Registry at %s", registry_location);
+        log_target_flag = VULKAN_LOADER_LAYER_BIT;
+        loader_log(inst, log_target_flag, 0, "Checking for Layer Manifest files in Registry at %s", registry_location);
     }
 
     // These calls look at the PNP/Device section of the registry.
@@ -707,17 +716,20 @@ VkResult windows_read_data_files_in_registry(const struct loader_instance *inst,
         // If we're looking for drivers we need to try enumerating adapters
         regHKR_result = windows_read_manifest_from_d3d_adapters(inst, &search_path, &reg_size, LoaderPnpDriverRegistryWide());
         if (regHKR_result == VK_INCOMPLETE) {
-            regHKR_result = windows_get_device_registry_files(inst, &search_path, &reg_size, LoaderPnpDriverRegistry());
+            regHKR_result =
+                windows_get_device_registry_files(inst, log_target_flag, &search_path, &reg_size, LoaderPnpDriverRegistry());
         }
     } else if (!strncmp(registry_location, VK_ELAYERS_INFO_REGISTRY_LOC, sizeof(VK_ELAYERS_INFO_REGISTRY_LOC))) {
         regHKR_result = windows_read_manifest_from_d3d_adapters(inst, &search_path, &reg_size, LoaderPnpELayerRegistryWide());
         if (regHKR_result == VK_INCOMPLETE) {
-            regHKR_result = windows_get_device_registry_files(inst, &search_path, &reg_size, LoaderPnpELayerRegistry());
+            regHKR_result =
+                windows_get_device_registry_files(inst, log_target_flag, &search_path, &reg_size, LoaderPnpELayerRegistry());
         }
     } else if (!strncmp(registry_location, VK_ILAYERS_INFO_REGISTRY_LOC, sizeof(VK_ILAYERS_INFO_REGISTRY_LOC))) {
         regHKR_result = windows_read_manifest_from_d3d_adapters(inst, &search_path, &reg_size, LoaderPnpILayerRegistryWide());
         if (regHKR_result == VK_INCOMPLETE) {
-            regHKR_result = windows_get_device_registry_files(inst, &search_path, &reg_size, LoaderPnpILayerRegistry());
+            regHKR_result =
+                windows_get_device_registry_files(inst, log_target_flag, &search_path, &reg_size, LoaderPnpILayerRegistry());
         }
     }
 
@@ -735,8 +747,8 @@ VkResult windows_read_data_files_in_registry(const struct loader_instance *inst,
     }
 
     if ((VK_SUCCESS != reg_result && VK_SUCCESS != regHKR_result) || NULL == search_path) {
-        if (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD) {
-            loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+        if (data_file_type == LOADER_DATA_FILE_MANIFEST_DRIVER) {
+            loader_log(inst, VULKAN_LOADER_ERROR_BIT | log_target_flag, 0,
                        "windows_read_data_files_in_registry: Registry lookup failed to get ICD manifest files.  Possibly missing "
                        "Vulkan driver?");
             vk_result = VK_ERROR_INCOMPATIBLE_DRIVER;
@@ -744,11 +756,11 @@ VkResult windows_read_data_files_in_registry(const struct loader_instance *inst,
             if (warn_if_not_present) {
                 if (data_file_type == LOADER_DATA_FILE_MANIFEST_LAYER) {
                     // This is only a warning for layers
-                    loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+                    loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                                "windows_read_data_files_in_registry: Registry lookup failed to get layer manifest files.");
                 } else {
                     // This is only a warning for general data files
-                    loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+                    loader_log(inst, VULKAN_LOADER_WARN_BIT | log_target_flag, 0,
                                "windows_read_data_files_in_registry: Registry lookup failed to get data files.");
                 }
             }
@@ -759,7 +771,7 @@ VkResult windows_read_data_files_in_registry(const struct loader_instance *inst,
     }
 
     // Now, parse the paths and add any manifest files found in them.
-    vk_result = add_data_files_in_path(inst, search_path, false, out_files, false);
+    vk_result = add_data_files(inst, search_path, out_files, false);
 
 out:
 
index a02151b052f6c05978855abc5974a93a808b2830..95ce645f4bf4e84c33e8161ea4c7ca5a1afa90f8 100644 (file)
@@ -70,8 +70,8 @@ bool windows_get_device_registry_entry(const struct loader_instance *inst, char
 //
 // *reg_data contains a string list of filenames as pointer.
 // When done using the returned string list, the caller should free the pointer.
-VkResult windows_get_device_registry_files(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size,
-                                           LPCSTR value_name);
+VkResult windows_get_device_registry_files(const struct loader_instance *inst, uint32_t log_target_flag, char **reg_data,
+                                           PDWORD reg_data_size, LPCSTR value_name);
 
 // Find the list of registry files (names within a key) in key "location".
 //
index 4d744a310cb370fc783e5835a55887b3d17b9e9c..48abb9623708d5d7c824fb467fefc74645e6e409 100644 (file)
@@ -550,11 +550,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr
     res = loader_icd_scan(ptr_instance, &ptr_instance->icd_tramp_list);
     if (res == VK_SUCCESS && ptr_instance->icd_tramp_list.count == 0) {
         // No drivers found
+        loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "vkCreateInstance: Found no drivers!");
         res = VK_ERROR_INCOMPATIBLE_DRIVER;
         goto out;
     }
     if (res != VK_SUCCESS) {
         if (res != VK_ERROR_OUT_OF_HOST_MEMORY && ptr_instance->icd_tramp_list.count == 0) {
+            loader_log(ptr_instance, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "vkCreateInstance: Found no drivers!");
             res = VK_ERROR_INCOMPATIBLE_DRIVER;
         }
         goto out;
index 4c7f0f2a29162ad1f10529836f3c7c1a10d39c7a..bda77eb294debc1c37567989c260feb466177af4 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *
- * Copyright (c) 2015-2021 The Khronos Group Inc.
- * Copyright (c) 2015-2021 Valve Corporation
- * Copyright (c) 2015-2021 LunarG, Inc.
+ * Copyright (c) 2015-2022 The Khronos Group Inc.
+ * Copyright (c) 2015-2022 Valve Corporation
+ * Copyright (c) 2015-2022 LunarG, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #endif
 
 // Environment Variable information
-#define VK_ICD_FILENAMES_ENV_VAR "VK_ICD_FILENAMES"
+#define VK_ICD_FILENAMES_ENV_VAR "VK_ICD_FILENAMES" // Deprecated
+#define VK_DRIVER_FILES_ENV_VAR "VK_DRIVER_FILES"
+#define VK_ADDITIONAL_DRIVER_FILES_ENV_VAR "VK_ADD_DRIVER_FILES"
 #define VK_LAYER_PATH_ENV_VAR "VK_LAYER_PATH"
+#define VK_ADDITIONAL_LAYER_PATH_ENV_VAR "VK_ADD_LAYER_PATH"
 
 // Override layer information
 #define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override"
index 12d108bcf15e43d969f5caab430be28f7aa5ffde..1c06c71f1cf15da68e37e2ac595625afbf606335 100644 (file)
@@ -29,6 +29,7 @@ add_executable(
     test_regression
         loader_testing_main.cpp
         loader_alloc_callback_tests.cpp
+        loader_envvar_tests.cpp
         loader_get_proc_addr_tests.cpp
         loader_debug_ext_tests.cpp
         loader_handle_validation_tests.cpp
index 5267a5a2e7778661e8db87cc16d40d6b37db0623..6002258f0149d88af301a0ea1cc10fc1b9a9f48d 100644 (file)
@@ -191,4 +191,4 @@ drivers and layers that are in the environment, allowing quick modification of t
 The `reset_test_icd()` and `reset_test_layer()` are similar to the above functions but additionally
 reset the layer or driver to its initial state.
 Use this if you need to reset a driver during a test.
-These functions are called on the drivers and layers when the framework is being create in each test.
\ No newline at end of file
+These functions are called on the drivers and layers when the framework is being create in each test.
index f78fab1a4fbdff1cd17b6b5f24c34ad5ad29ad0a..3377af2323af4683c2b2df17e9a8875a8f15547f 100644 (file)
@@ -429,7 +429,7 @@ VKAPI_ATTR VkResult VKAPI_CALL wrap_vkEnumerateDeviceExtensionProperties(VkPhysi
                     strncpy_s(pProperties[ext_count].extensionName, VK_MAX_EXTENSION_NAME_SIZE, VK_KHR_MAINTENANCE1_EXTENSION_NAME,
                               strlen(VK_KHR_MAINTENANCE1_EXTENSION_NAME) + 1);
 #else
-                    strcpy(pProperties[ext_count].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
+                    strncpy(pProperties[ext_count].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE);
 #endif
                     pProperties[ext_count].specVersion = 2;
                     ext_count++;
@@ -442,7 +442,8 @@ VKAPI_ATTR VkResult VKAPI_CALL wrap_vkEnumerateDeviceExtensionProperties(VkPhysi
                               VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
                               strlen(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME) + 1);
 #else
-                    strcpy(pProperties[ext_count].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME);
+                    strncpy(pProperties[ext_count].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
+                            VK_MAX_EXTENSION_NAME_SIZE);
 #endif
                     pProperties[ext_count].specVersion = 1;
                     ext_count++;
@@ -598,7 +599,7 @@ PFN_vkVoidFunction layer_intercept_instance_proc(wrapped_inst_obj *inst, const c
 
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     if (!strcmp(name, "CreateAndroidSurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkCreateAndroidSurfaceKHR;
-#endif  // VK_USE_PLATFORM_WIN32_KHR
+#endif  // VK_USE_PLATFORM_ANDROID_KHR
 
 #ifdef VK_USE_PLATFORM_WIN32_KHR
     if (!strcmp(name, "CreateWin32SurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkCreateWin32SurfaceKHR;
index 5d5f2ad32505431e84f3475cdfaf7adc47aeb6b1..e2b80fa76b8d9e042acb08d38176e1ff243a3a31 100644 (file)
@@ -182,7 +182,7 @@ TestLayer& TestLayerHandle::reset_layer() noexcept {
 }
 fs::path TestLayerHandle::get_layer_full_path() noexcept { return layer_library.lib_path; }
 
-FrameworkEnvironment::FrameworkEnvironment(DebugMode debug_mode) noexcept
+FrameworkEnvironment::FrameworkEnvironment(DebugMode debug_mode, bool override_icds, bool override_layers) noexcept
     : platform_shim(debug_mode),
       null_folder(FRAMEWORK_BUILD_DIRECTORY, "null_dir", debug_mode),
       icd_folder(FRAMEWORK_BUILD_DIRECTORY, "icd_manifests", debug_mode),
@@ -191,8 +191,16 @@ FrameworkEnvironment::FrameworkEnvironment(DebugMode debug_mode) noexcept
       vulkan_functions() {
     platform_shim->redirect_all_paths(null_folder.location());
 
-    platform_shim->set_path(ManifestCategory::icd, icd_folder.location());
-    platform_shim->set_path(ManifestCategory::explicit_layer, explicit_layer_folder.location());
+    if (override_icds) {
+        platform_shim->set_path(ManifestCategory::icd, null_folder.location());
+    } else {
+        platform_shim->set_path(ManifestCategory::icd, icd_folder.location());
+    }
+    if (override_layers) {
+        platform_shim->set_path(ManifestCategory::explicit_layer, null_folder.location());
+    } else {
+        platform_shim->set_path(ManifestCategory::explicit_layer, explicit_layer_folder.location());
+    }
     platform_shim->set_path(ManifestCategory::implicit_layer, implicit_layer_folder.location());
 }
 
@@ -221,7 +229,13 @@ void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
             env_var_vk_icd_filenames += OS_ENV_VAR_LIST_SEPARATOR;
         }
         env_var_vk_icd_filenames += (icd_folder.location() / full_json_name).str();
-        set_env_var("VK_ICD_FILENAMES", env_var_vk_icd_filenames);
+        set_env_var("VK_DRIVER_FILES", env_var_vk_icd_filenames);
+    } else  if (icd_details.use_add_env_var_icd_filenames) {
+        if (!add_env_var_vk_icd_filenames.empty()) {
+            add_env_var_vk_icd_filenames += OS_ENV_VAR_LIST_SEPARATOR;
+        }
+        add_env_var_vk_icd_filenames += (icd_folder.location() / full_json_name).str();
+        set_env_var("VK_ADD_DRIVER_FILES", add_env_var_vk_icd_filenames);
     } else {
         platform_shim->add_manifest(ManifestCategory::icd, driver_loc);
     }
index e304d347aec785cf5f77ce15e3970dab33521be9..2cf228fb62dbe8ddd8c33a90be7218782e0a21de 100644 (file)
@@ -308,6 +308,7 @@ struct TestICDDetails {
     BUILDER_VALUE(TestICDDetails, uint32_t, api_version, VK_API_VERSION_1_0);
     BUILDER_VALUE(TestICDDetails, std::string, json_name, "test_icd");
     BUILDER_VALUE(TestICDDetails, bool, use_env_var_icd_filenames, false);
+    BUILDER_VALUE(TestICDDetails, bool, use_add_env_var_icd_filenames, false);
     BUILDER_VALUE(TestICDDetails, bool, is_fake, false);
 };
 
@@ -322,7 +323,7 @@ struct TestLayerDetails {
 };
 
 struct FrameworkEnvironment {
-    FrameworkEnvironment(DebugMode debug_mode = DebugMode::none) noexcept;
+    FrameworkEnvironment(DebugMode debug_mode = DebugMode::none, bool override_icds = false, bool override_layers = false) noexcept;
 
     void add_icd(TestICDDetails icd_details) noexcept;
     void add_implicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept;
@@ -352,6 +353,7 @@ struct FrameworkEnvironment {
     std::vector<TestLayerHandle> layers;
 
     std::string env_var_vk_icd_filenames;
+    std::string add_env_var_vk_icd_filenames;
 
    private:
     void add_layer_impl(TestLayerDetails layer_details, fs::FolderManager& folder_manager, ManifestCategory category);
diff --git a/tests/loader_envvar_tests.cpp b/tests/loader_envvar_tests.cpp
new file mode 100644 (file)
index 0000000..7515bd4
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2021-2022 The Khronos Group Inc.
+ * Copyright (c) 2021-2022 Valve Corporation
+ * Copyright (c) 2021-2022 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE 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 MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ * Author: Charles Giessen <charles@lunarg.com>
+ * Author: Mark Young <markylunarg.com>
+ */
+
+#include "test_environment.h"
+
+class EnvVarICDOverrideSetup : public ::testing::Test {
+   protected:
+    virtual void SetUp() {
+        remove_env_var("VK_ICD_FILENAMES");
+        remove_env_var("VK_DRIVER_FILES");
+        remove_env_var("VK_ADD_DRIVER_FILES");
+    }
+
+    virtual void TearDown() {
+        remove_env_var("VK_ICD_FILENAMES");
+        remove_env_var("VK_DRIVER_FILES");
+        remove_env_var("VK_ADD_DRIVER_FILES");
+    }
+};
+
+// Don't support vk_icdNegotiateLoaderICDInterfaceVersion
+// Loader calls vk_icdGetInstanceProcAddr second
+// does not support vk_icdGetInstanceProcAddr
+// must export vkGetInstanceProcAddr, vkCreateInstance, vkEnumerateInstanceExtensionProperties
+TEST(EnvVarICDOverrideSetup, version_0_none) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_use_env_var_icd_filenames(true));
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    ASSERT_EQ(env.get_test_icd(0).called_vk_icd_gipa, CalledICDGIPA::vk_gipa);
+}
+
+// Don't support vk_icdNegotiateLoaderICDInterfaceVersion
+// the loader calls vk_icdGetInstanceProcAddr first
+TEST(EnvVarICDOverrideSetup, version_1_icd_gipa) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA).set_use_env_var_icd_filenames(true));
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    ASSERT_EQ(env.get_test_icd(0).called_vk_icd_gipa, CalledICDGIPA::vk_icd_gipa);
+}
+
+// support vk_icdNegotiateLoaderICDInterfaceVersion but not vk_icdGetInstanceProcAddr
+// should assert that `interface_vers == 0` due to version mismatch, only checkable in Debug Mode
+TEST(EnvVarICDOverrideSetup, version_negotiate_interface_version_death_test) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NEGOTIATE_INTERFACE_VERSION).set_use_env_var_icd_filenames(true));
+
+    InstWrapper inst{env.vulkan_functions};
+
+#if !defined(NDEBUG)
+#if defined(WIN32)
+    ASSERT_DEATH(inst.CheckCreate(), "");
+#else
+    ASSERT_DEATH(inst.CheckCreate(), "interface_vers == 0");
+#endif
+#else
+    inst.CheckCreate();
+#endif
+}
+
+// export vk_icdNegotiateLoaderICDInterfaceVersion and vk_icdGetInstanceProcAddr
+TEST(EnvVarICDOverrideSetup, version_2_negotiate_interface_version_and_icd_gipa) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_use_env_var_icd_filenames(true));
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    ASSERT_EQ(env.get_test_icd(0).called_vk_icd_gipa, CalledICDGIPA::vk_icd_gipa);
+}
+
+// Test VK_DRIVER_FILES environment variable
+TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVar) {
+    FrameworkEnvironment env{DebugMode::none, true};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_use_env_var_icd_filenames(true));
+    env.get_test_icd(0).physical_devices.emplace_back("pd0");
+
+    InstWrapper inst1{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
+    inst1.CheckCreate();
+    EXPECT_FALSE(
+        env.debug_log.find("Ignoring override VK_ICD_FILENAMES, VK_DRIVER_FILES, and VK_ADD_DRIVER_FILES due to high-integrity"));
+
+    std::array<VkPhysicalDevice, 5> phys_devs_array;
+    uint32_t phys_dev_count = 1;
+    ASSERT_EQ(inst1->vkEnumeratePhysicalDevices(inst1.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
+    ASSERT_EQ(phys_dev_count, 1);
+
+    for (uint32_t add = 0; add < 2; ++add) {
+        env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_use_env_var_icd_filenames(true));
+        env.get_test_icd(add + 1).physical_devices.emplace_back("pd" + std::to_string(add) + "0");
+        env.get_test_icd(add + 1).physical_devices.emplace_back("pd" + std::to_string(add) + "1");
+    }
+
+    env.debug_log.clear();
+
+    InstWrapper inst2{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
+    inst2.CheckCreate();
+
+    phys_dev_count = 5;
+    ASSERT_EQ(inst2->vkEnumeratePhysicalDevices(inst2.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
+    ASSERT_EQ(phys_dev_count, 5);
+
+    env.debug_log.clear();
+
+    env.platform_shim->set_elevated_privilege(true);
+
+    InstWrapper inst3{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log);
+    inst3.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+
+    EXPECT_TRUE(env.debug_log.find("vkCreateInstance: Found no drivers!"));
+
+    env.platform_shim->set_elevated_privilege(false);
+
+    remove_env_var("VK_DRIVER_FILES");
+}
+
+#if defined(__linux__) || defined(__FreeBSD__)
+// Make sure the loader reports the correct message based on if USE_UNSAFE_FILE_SEARCH is set or not
+TEST(EnvVarICDOverrideSetup, NonSecureEnvVarLookup) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
+    env.get_test_icd().physical_devices.emplace_back("physical_device_0");
+
+    DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, log);
+    inst.CheckCreate();
+
+#if !defined(USE_UNSAFE_FILE_SEARCH)
+    ASSERT_FALSE(log.find("Loader is using non-secure environment variable lookup for"));
+#else
+    ASSERT_TRUE(log.find("Loader is using non-secure environment variable lookup for"));
+#endif
+}
+
+// Check for proper handling of paths specified via environment variables.
+TEST(EnvVarICDOverrideSetup, XDG) {
+    // Set up a layer path that includes default and user-specified locations,
+    // so that the test app can find them.  Include some badly specified elements as well.
+    // Need to redirect the 'home' directory
+    fs::path HOME = "/home/fake_home";
+    set_env_var("HOME", HOME.str());
+    set_env_var("XDG_CONFIG_DIRS", ":/tmp/goober:::::/tmp/goober/::::");
+    set_env_var("XDG_CONFIG_HOME", ":/tmp/goober:::::/tmp/goober2/::::");
+    set_env_var("XDG_DATA_DIRS", "::::/tmp/goober3:/tmp/goober4/with spaces:::");
+    set_env_var("XDG_DATA_HOME", "::::/tmp/goober3:/tmp/goober4/with spaces:::");
+
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
+    env.get_test_icd().physical_devices.push_back({});
+
+    InstWrapper inst{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+
+    auto check_paths = [](DebugUtilsLogger const& debug_log, ManifestCategory category, fs::path const& HOME) {
+        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober/vulkan") / category_path_name(category)).str()));
+        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober2/vulkan") / category_path_name(category)).str()));
+        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober3/vulkan") / category_path_name(category)).str()));
+        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober4/with spaces/vulkan") / category_path_name(category)).str()));
+    };
+    check_paths(env.debug_log, ManifestCategory::icd, HOME);
+    check_paths(env.debug_log, ManifestCategory::implicit_layer, HOME);
+    check_paths(env.debug_log, ManifestCategory::explicit_layer, HOME);
+}
+#endif
+
+// Test VK_ADD_DRIVER_FILES environment variable
+TEST(EnvVarICDOverrideSetup, TestOnlyAddDriverEnvVar) {
+    FrameworkEnvironment env{DebugMode::none, true};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_use_add_env_var_icd_filenames(true));
+    env.get_test_icd(0).physical_devices.emplace_back("pd0");
+
+    InstWrapper inst1{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
+    inst1.CheckCreate();
+
+    std::array<VkPhysicalDevice, 1> phys_devs_array;
+    uint32_t phys_dev_count = 1;
+    ASSERT_EQ(inst1->vkEnumeratePhysicalDevices(inst1.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
+    ASSERT_EQ(phys_dev_count, 1);
+
+    env.platform_shim->set_elevated_privilege(true);
+
+    InstWrapper inst2{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
+    inst2.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+
+    EXPECT_TRUE(env.debug_log.find("vkCreateInstance: Found no drivers!"));
+
+    env.platform_shim->set_elevated_privilege(false);
+
+    remove_env_var("VK_ADD_DRIVER_FILES");
+}
+
+// Test Both VK_DRIVER_FILES and VK_ADD_DRIVER_FILES environment variable
+TEST(EnvVarICDOverrideSetup, TestBothDriverEnvVars) {
+    FrameworkEnvironment env{DebugMode::none, true};
+
+    // Add a driver that isn't enabled with the environment variable
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_use_env_var_icd_filenames(true));
+    env.get_test_icd(0).physical_devices.emplace_back("pd0");
+    env.get_test_icd(0).physical_devices.emplace_back("pd1");
+
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_use_add_env_var_icd_filenames(true));
+    env.get_test_icd(0).physical_devices.emplace_back("pd2");
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    // The enumerate should now detect both drivers because we used the add
+    std::array<VkPhysicalDevice, 3> phys_devs_array;
+    uint32_t phys_dev_count = 3;
+    ASSERT_EQ(inst->vkEnumeratePhysicalDevices(inst.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
+    ASSERT_EQ(phys_dev_count, 3);
+
+    remove_env_var("VK_DRIVER_FILES");
+    remove_env_var("VK_ADD_DRIVER_FILES");
+}
+
+#if defined(__linux__) || defined(__FreeBSD__)
+// Test VK_LAYER_PATH environment variable
+TEST(EnvVarICDOverrideSetup, TestOnlyLayerEnvVar) {
+    // Set up a layer path that includes default and user-specified locations,
+    // so that the test app can find them.  Include some badly specified elements as well.
+    // Need to redirect the 'home' directory
+    fs::path HOME = "/home/fake_home";
+    set_env_var("HOME", HOME.str());
+    std::string vk_layer_path = ":/tmp/carol::::/:";
+    vk_layer_path += (HOME / "/ with spaces/:::::/tandy:").str();
+    set_env_var("VK_LAYER_PATH", vk_layer_path);
+
+    FrameworkEnvironment env{DebugMode::none, false, true};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
+    env.get_test_icd().physical_devices.push_back({});
+    env.platform_shim->redirect_path("/tmp/carol", env.explicit_layer_folder.location());
+
+    const char* layer_name = "TestLayer";
+    env.add_explicit_layer(
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
+        "test_layer.json");
+
+    InstWrapper inst1{env.vulkan_functions};
+    inst1.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
+    inst1.CheckCreate();
+
+    // look for VK_LAYER_PATHS
+    EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
+    EXPECT_TRUE(env.debug_log.find("/tandy"));
+    EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/").str()));
+
+    env.debug_log.clear();
+
+    env.platform_shim->set_elevated_privilege(true);
+
+    InstWrapper inst2{env.vulkan_functions};
+    inst2.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
+    inst2.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
+
+    EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
+
+    env.platform_shim->set_elevated_privilege(false);
+
+    remove_env_var("VK_LAYER_PATH");
+}
+
+// Test VK_ADD_LAYER_PATH environment variable
+TEST(EnvVarICDOverrideSetup, TestOnlyAddLayerEnvVar) {
+    // Set up a layer path that includes default and user-specified locations,
+    // so that the test app can find them.  Include some badly specified elements as well.
+    // Need to redirect the 'home' directory
+    fs::path HOME = "/home/fake_home";
+    set_env_var("HOME", HOME.str());
+    std::string vk_layer_path = ":/tmp/carol::::/:";
+    vk_layer_path += (HOME / "/ with spaces/:::::/tandy:").str();
+    set_env_var("VK_ADD_LAYER_PATH", vk_layer_path);
+
+    FrameworkEnvironment env{DebugMode::none, false, true};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
+    env.get_test_icd().physical_devices.push_back({});
+    env.platform_shim->redirect_path("/tmp/carol", env.explicit_layer_folder.location());
+
+    const char* layer_name = "TestLayer";
+    env.add_explicit_layer(
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
+        "test_layer.json");
+
+    InstWrapper inst1{env.vulkan_functions};
+    inst1.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
+    inst1.CheckCreate();
+
+    // look for VK_ADD_LAYER_PATHS
+    EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
+    EXPECT_TRUE(env.debug_log.find("/tandy"));
+    EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/").str()));
+
+    env.debug_log.clear();
+
+    env.platform_shim->set_elevated_privilege(true);
+
+    InstWrapper inst2{env.vulkan_functions};
+    inst2.create_info.add_layer(layer_name);
+    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
+    inst2.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
+
+    EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
+
+    env.platform_shim->set_elevated_privilege(false);
+
+    remove_env_var("VK_ADD_LAYER_PATH");
+}
+
+#endif
index c865e8bb5b13b6864b3036e990f7936b98a7cf9a..db6a5c52f1ad76af673fa44f0257834c9be2bbc7 100644 (file)
@@ -2121,105 +2121,6 @@ TEST_F(EnumeratePhysicalDeviceGroups, FakePNext) {
     }
 }
 
-#if defined(__linux__) || defined(__FreeBSD__)
-// Make sure the loader reports the correct message based on if USE_UNSAFE_FILE_SEARCH is set or not
-TEST(EnvironmentVariables, NonSecureEnvVarLookup) {
-    FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
-    env.get_test_icd().physical_devices.emplace_back("physical_device_0");
-
-    DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
-    InstWrapper inst{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst.create_info, log);
-    inst.CheckCreate();
-
-#if !defined(USE_UNSAFE_FILE_SEARCH)
-    ASSERT_FALSE(log.find("Loader is using non-secure environment variable lookup for"));
-#else
-    ASSERT_TRUE(log.find("Loader is using non-secure environment variable lookup for"));
-#endif
-}
-
-// Check for proper handling of paths specified via environment variables.
-TEST(EnvironmentVariables, XDG) {
-    // Set up a layer path that includes default and user-specified locations,
-    // so that the test app can find them.  Include some badly specified elements as well.
-    // Need to redirect the 'home' directory
-    fs::path HOME = "/home/fake_home";
-    set_env_var("HOME", HOME.str());
-    set_env_var("XDG_CONFIG_DIRS", ":/tmp/goober:::::/tmp/goober/::::");
-    set_env_var("XDG_CONFIG_HOME", ":/tmp/goober:::::/tmp/goober2/::::");
-    set_env_var("XDG_DATA_DIRS", "::::/tmp/goober3:/tmp/goober4/with spaces:::");
-    set_env_var("XDG_DATA_HOME", "::::/tmp/goober3:/tmp/goober4/with spaces:::");
-
-    FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
-    env.get_test_icd().physical_devices.push_back({});
-
-    InstWrapper inst{env.vulkan_functions};
-    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
-    inst.CheckCreate();
-
-    auto check_paths = [](DebugUtilsLogger const& debug_log, ManifestCategory category, fs::path const& HOME) {
-        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober/vulkan") / category_path_name(category)).str()));
-        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober2/vulkan") / category_path_name(category)).str()));
-        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober3/vulkan") / category_path_name(category)).str()));
-        EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober4/with spaces/vulkan") / category_path_name(category)).str()));
-    };
-    check_paths(env.debug_log, ManifestCategory::icd, HOME);
-    check_paths(env.debug_log, ManifestCategory::implicit_layer, HOME);
-    check_paths(env.debug_log, ManifestCategory::explicit_layer, HOME);
-}
-
-// Check for proper handling of paths specified via environment variables.
-TEST(EnvironmentVariables, VK_LAYER_PATH) {
-    // Set up a layer path that includes default and user-specified locations,
-    // so that the test app can find them.  Include some badly specified elements as well.
-    // Need to redirect the 'home' directory
-    fs::path HOME = "/home/fake_home";
-    set_env_var("HOME", HOME.str());
-    std::string vk_layer_path = ":/tmp/carol::::/:";
-    vk_layer_path += (HOME / "/ with spaces/:::::/tandy:").str();
-    set_env_var("VK_LAYER_PATH", vk_layer_path);
-
-    FrameworkEnvironment env{};
-    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
-    env.get_test_icd().physical_devices.push_back({});
-    env.platform_shim->redirect_path("/tmp/carol", env.explicit_layer_folder.location());
-
-    const char* layer_name = "TestLayer";
-    env.add_explicit_layer(
-        ManifestLayer{}.add_layer(
-            ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
-        "test_layer.json");
-
-    InstWrapper inst1{env.vulkan_functions};
-    inst1.create_info.add_layer(layer_name);
-    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
-    inst1.CheckCreate();
-
-    // look for VK_LAYER_PATHS
-    EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
-    EXPECT_TRUE(env.debug_log.find("/tandy"));
-    EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/").str()));
-
-    env.debug_log.clear();
-
-    env.platform_shim->set_elevated_privilege(true);
-
-    InstWrapper inst2{env.vulkan_functions};
-    inst2.create_info.add_layer(layer_name);
-    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
-    inst2.CheckCreate();
-
-    EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
-
-    env.platform_shim->set_elevated_privilege(false);
-
-    remove_env_var("VK_LAYER_PATH");
-}
-#endif
-
 TEST(ExtensionManual, ToolingProperties) {
     VkPhysicalDeviceToolPropertiesEXT icd_tool_props{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT,
                                                      nullptr,
index a2aefd0075024ff94f555f9de72b70b0a126f836..1ddfbfa472effa1a43f53dc99df1aad1722d546b 100644 (file)
@@ -50,7 +50,10 @@ int main(int argc, char** argv) {
 
     // make sure the tests don't find these env-vars if they were set on the system
     remove_env_var("VK_ICD_FILENAMES");
+    remove_env_var("VK_DRIVER_FILES");
+    remove_env_var("VK_ADD_DRIVER_FILES");
     remove_env_var("VK_LAYER_PATH");
+    remove_env_var("VK_ADD_LAYER_PATH");
     remove_env_var("VK_INSTANCE_LAYERS");
     remove_env_var("VK_LOADER_DEBUG");
     remove_env_var("VK_LOADER_DISABLE_INST_EXT_FILTER");
index 27a86c45c59c4fde1ca18b87c73f0d60455b152c..8ef47abe7df7518430952ce0478b058e1e68697a 100644 (file)
 
 #include "test_environment.h"
 
-class EnvVarICDOverrideSetup : public ::testing::Test {
-   protected:
-    virtual void SetUp() { env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment()); }
-
-    virtual void TearDown() {
-        remove_env_var("VK_ICD_FILENAMES");
-        env.reset();
-    }
-    std::unique_ptr<FrameworkEnvironment> env;
-};
-
-// Don't support vk_icdNegotiateLoaderICDInterfaceVersion
-// Loader calls vk_icdGetInstanceProcAddr second
-// does not support vk_icdGetInstanceProcAddr
-// must export vkGetInstanceProcAddr, vkCreateInstance, vkEnumerateInstanceExtensionProperties
-TEST_F(EnvVarICDOverrideSetup, version_0_none) {
-    env->add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_use_env_var_icd_filenames(true));
-    auto& driver = env->reset_icd();
-
-    InstWrapper inst{env->vulkan_functions};
-    inst.CheckCreate();
-
-    ASSERT_EQ(driver.called_vk_icd_gipa, CalledICDGIPA::vk_gipa);
-}
-
-// Don't support vk_icdNegotiateLoaderICDInterfaceVersion
-// the loader calls vk_icdGetInstanceProcAddr first
-TEST_F(EnvVarICDOverrideSetup, version_1_icd_gipa) {
-    env->add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA).set_use_env_var_icd_filenames(true));
-    auto& driver = env->reset_icd();
-
-    InstWrapper inst{env->vulkan_functions};
-    inst.CheckCreate();
-
-    ASSERT_EQ(driver.called_vk_icd_gipa, CalledICDGIPA::vk_icd_gipa);
-}
-
-// support vk_icdNegotiateLoaderICDInterfaceVersion but not vk_icdGetInstanceProcAddr
-// should assert that `interface_vers == 0` due to version mismatch, only checkable in Debug Mode
-TEST_F(EnvVarICDOverrideSetup, version_negotiate_interface_version_death_test) {
-    env->add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NEGOTIATE_INTERFACE_VERSION).set_use_env_var_icd_filenames(true));
-    env->reset_icd();
-
-    InstWrapper inst{env->vulkan_functions};
-
-#if !defined(NDEBUG)
-#if defined(WIN32)
-    ASSERT_DEATH(inst.CheckCreate(), "");
-#else
-    ASSERT_DEATH(inst.CheckCreate(), "interface_vers == 0");
-#endif
-#else
-    inst.CheckCreate();
-#endif
-}
-
-// export vk_icdNegotiateLoaderICDInterfaceVersion and vk_icdGetInstanceProcAddr
-TEST_F(EnvVarICDOverrideSetup, version_2_negotiate_interface_version_and_icd_gipa) {
-    env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_use_env_var_icd_filenames(true));
-    auto& driver = env->reset_icd();
-
-    InstWrapper inst{env->vulkan_functions};
-    inst.CheckCreate();
-
-    ASSERT_EQ(driver.called_vk_icd_gipa, CalledICDGIPA::vk_icd_gipa);
-}
-
 class ICDInterfaceVersion2Plus : public ::testing::Test {
    protected:
     virtual void SetUp() {