diff options
author | Andrew Naumov <andrew-naumov@yandex-team.ru> | 2022-02-14 14:21:43 +0300 |
---|---|---|
committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2022-06-24 22:14:10 +0300 |
commit | 5249c8f8690d0e867f1c0ff16b428f07a805a4d2 (patch) | |
tree | 688558e1cdd269917f19a44d70b837f91f30bf43 | |
parent | 865626abbafda93a236398ac35627407d62dbe6f (diff) |
loader: Add unicode support
-rw-r--r-- | loader/allocation.h | 7 | ||||
-rw-r--r-- | loader/get_environment.c | 40 | ||||
-rw-r--r-- | loader/loader.c | 11 | ||||
-rw-r--r-- | loader/loader_windows.c | 8 | ||||
-rw-r--r-- | loader/stack_allocation.h | 41 | ||||
-rw-r--r-- | loader/vk_loader_platform.h | 42 | ||||
-rw-r--r-- | tests/framework/framework_config.h.in | 4 | ||||
-rw-r--r-- | tests/framework/icd/CMakeLists.txt | 6 | ||||
-rw-r--r-- | tests/framework/test_util.cpp | 97 | ||||
-rw-r--r-- | tests/framework/test_util.h | 14 | ||||
-rw-r--r-- | tests/loader_envvar_tests.cpp | 13 |
11 files changed, 222 insertions, 61 deletions
diff --git a/loader/allocation.h b/loader/allocation.h index 3f272d925..6e2d7ef23 100644 --- a/loader/allocation.h +++ b/loader/allocation.h @@ -29,6 +29,7 @@ #pragma once #include "loader_common.h" +#include "stack_allocation.h" void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocation_scope); void *loader_instance_heap_calloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocation_scope); @@ -59,9 +60,3 @@ void loader_free_with_instance_fallback(const VkAllocationCallbacks *pAllocator, void *pMemory); void *loader_realloc_with_instance_fallback(const VkAllocationCallbacks *pAllocator, const struct loader_instance *instance, void *pMemory, size_t orig_size, size_t size, VkSystemAllocationScope allocation_scope); - -#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) -#define loader_stack_alloc(size) alloca(size) -#elif defined(_WIN32) -#define loader_stack_alloc(size) _alloca(size) -#endif // defined(_WIN32) diff --git a/loader/get_environment.c b/loader/get_environment.c index a389a9333..424123895 100644 --- a/loader/get_environment.c +++ b/loader/get_environment.c @@ -106,22 +106,40 @@ bool is_high_integrity() { } char *loader_getenv(const char *name, const struct loader_instance *inst) { - char *retVal; - DWORD valSize; - - valSize = GetEnvironmentVariableA(name, NULL, 0); + int name_utf16_size = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0); + if (name_utf16_size <= 0) { + return NULL; + } + wchar_t *name_utf16 = (wchar_t *)loader_stack_alloc(name_utf16_size * sizeof(wchar_t)); + if (MultiByteToWideChar(CP_UTF8, 0, name, -1, name_utf16, name_utf16_size) != name_utf16_size) { + return NULL; + } - // valSize DOES include the null terminator, so for any set variable + DWORD val_size = GetEnvironmentVariableW(name_utf16, NULL, 0); + // val_size DOES include the null terminator, so for any set variable // will always be at least 1. If it's 0, the variable wasn't set. - if (valSize == 0) return NULL; - - retVal = loader_instance_heap_alloc(inst, valSize, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (val_size == 0) { + return NULL; + } - if (NULL != retVal) { - GetEnvironmentVariableA(name, retVal, valSize); + wchar_t *val = (wchar_t *)loader_stack_alloc(val_size * sizeof(wchar_t)); + if (GetEnvironmentVariableW(name_utf16, val, val_size) != val_size - 1) { + return NULL; } - return retVal; + int val_utf8_size = WideCharToMultiByte(CP_UTF8, 0, val, -1, NULL, 0, NULL, NULL); + if (val_utf8_size <= 0) { + return NULL; + } + char *val_utf8 = (char *)loader_instance_heap_alloc(inst, val_utf8_size * sizeof(char), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (val_utf8 == NULL) { + return NULL; + } + if (WideCharToMultiByte(CP_UTF8, 0, val, -1, val_utf8, val_utf8_size, NULL, NULL) != val_utf8_size) { + loader_instance_heap_free(inst, val_utf8); + return NULL; + } + return val_utf8; } char *loader_secure_getenv(const char *name, const struct loader_instance *inst) { diff --git a/loader/loader.c b/loader/loader.c index fd59f199c..da63d0d72 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -1644,7 +1644,18 @@ static VkResult loader_get_json(const struct loader_instance *inst, const char * *json = NULL; +#if defined(_WIN32) + int filename_utf16_size = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0); + if (filename_utf16_size > 0) { + wchar_t *filename_utf16 = (wchar_t *)loader_stack_alloc(filename_utf16_size * sizeof(wchar_t)); + if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_utf16, filename_utf16_size) == filename_utf16_size) { + file = _wfopen(filename_utf16, L"rb"); + } + } +#else file = fopen(filename, "rb"); +#endif + if (!file) { loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to open JSON file %s", filename); res = VK_ERROR_INITIALIZATION_FAILED; diff --git a/loader/loader_windows.c b/loader/loader_windows.c index cc469a4e0..c7fbab9c8 100644 --- a/loader/loader_windows.c +++ b/loader/loader_windows.c @@ -73,10 +73,10 @@ void windows_initialization(void) { // and not after the first call that has been statically linked LoadLibrary("gdi32.dll"); - TCHAR systemPath[MAX_PATH] = ""; - GetSystemDirectory(systemPath, MAX_PATH); - StringCchCat(systemPath, MAX_PATH, TEXT("\\dxgi.dll")); - HMODULE dxgi_module = LoadLibrary(systemPath); + wchar_t systemPath[MAX_PATH] = L""; + GetSystemDirectoryW(systemPath, MAX_PATH); + StringCchCatW(systemPath, MAX_PATH, L"\\dxgi.dll"); + HMODULE dxgi_module = LoadLibraryW(systemPath); fpCreateDXGIFactory1 = dxgi_module == NULL ? NULL : (PFN_CreateDXGIFactory1)GetProcAddress(dxgi_module, "CreateDXGIFactory1"); #if !defined(NDEBUG) diff --git a/loader/stack_allocation.h b/loader/stack_allocation.h new file mode 100644 index 000000000..0ddd5ca3c --- /dev/null +++ b/loader/stack_allocation.h @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 2014-2022 The Khronos Group Inc. + * Copyright (c) 2014-2022 Valve Corporation + * Copyright (c) 2014-2022 LunarG, Inc. + * Copyright (C) 2015 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Jon Ashburn <jon@lunarg.com> + * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> + * Author: Chia-I Wu <olvaffe@gmail.com> + * Author: Chia-I Wu <olv@lunarg.com> + * Author: Mark Lobodzinski <mark@LunarG.com> + * Author: Lenny Komow <lenny@lunarg.com> + * Author: Charles Giessen <charles@lunarg.com> + */ + +#pragma once + +#if defined(_WIN32) +#include <malloc.h> +#else +#include <alloca.h> +#endif + +#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__) || defined(__FreeBSD__) +#define loader_stack_alloc(size) alloca(size) +#elif defined(_WIN32) +#define loader_stack_alloc(size) _alloca(size) +#endif // defined(_WIN32) diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h index 62f74312e..993fe8306 100644 --- a/loader/vk_loader_platform.h +++ b/loader/vk_loader_platform.h @@ -76,6 +76,7 @@ #include "vk_loader_layer.h" #include "vk_layer_dispatch_table.h" #include "vk_loader_extensions.h" +#include "stack_allocation.h" #if defined(__GNUC__) && __GNUC__ >= 4 #define LOADER_EXPORT __attribute__((visibility("default"))) @@ -374,7 +375,15 @@ static inline const wchar_t *LoaderPnpILayerRegistryWide() { // File IO static bool loader_platform_file_exists(const char *path) { - if ((_access(path, 0)) == -1) + int path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + if (path_utf16_size <= 0) { + return false; + } + wchar_t *path_utf16 = (wchar_t *)loader_stack_alloc(path_utf16_size * sizeof(wchar_t)); + if (MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, path_utf16_size) != path_utf16_size) { + return false; + } + if (_waccess(path_utf16, 0) == -1) return false; else return true; @@ -410,21 +419,40 @@ static inline char *loader_platform_dirname(char *path) { } static inline char *loader_platform_executable_path(char *buffer, size_t size) { - DWORD ret = GetModuleFileName(NULL, buffer, (DWORD)size); - if (ret == 0) return NULL; - if (ret > size) return NULL; - buffer[ret] = '\0'; + wchar_t *buffer_utf16 = (wchar_t *)loader_stack_alloc(size * sizeof(wchar_t)); + DWORD ret = GetModuleFileNameW(NULL, buffer_utf16, (DWORD)size); + if (ret == 0) { + return NULL; + } + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return NULL; + } + int buffer_utf8_size = WideCharToMultiByte(CP_UTF8, 0, buffer_utf16, -1, NULL, 0, NULL, NULL); + if (buffer_utf8_size <= 0 || (size_t)buffer_utf8_size > size) { + return NULL; + } + if (WideCharToMultiByte(CP_UTF8, 0, buffer_utf16, -1, buffer, buffer_utf8_size, NULL, NULL) != buffer_utf8_size) { + return NULL; + } return buffer; } // Dynamic Loading: typedef HMODULE loader_platform_dl_handle; static loader_platform_dl_handle loader_platform_open_library(const char *lib_path) { + int lib_path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, lib_path, -1, NULL, 0); + if (lib_path_utf16_size <= 0) { + return NULL; + } + wchar_t *lib_path_utf16 = (wchar_t *)loader_stack_alloc(lib_path_utf16_size * sizeof(wchar_t)); + if (MultiByteToWideChar(CP_UTF8, 0, lib_path, -1, lib_path_utf16, lib_path_utf16_size) != lib_path_utf16_size) { + return NULL; + } // Try loading the library the original way first. - loader_platform_dl_handle lib_handle = LoadLibrary(lib_path); + loader_platform_dl_handle lib_handle = LoadLibraryW(lib_path_utf16); if (lib_handle == NULL && GetLastError() == ERROR_MOD_NOT_FOUND) { // If that failed, then try loading it with broader search folders. - lib_handle = LoadLibraryEx(lib_path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); + lib_handle = LoadLibraryExW(lib_path_utf16, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); } return lib_handle; } diff --git a/tests/framework/framework_config.h.in b/tests/framework/framework_config.h.in index fca36cb57..4b956937b 100644 --- a/tests/framework/framework_config.h.in +++ b/tests/framework/framework_config.h.in @@ -41,6 +41,10 @@ #define TEST_ICD_PATH_VERSION_2 "$<TARGET_FILE:test_icd_version_2>" +#define TEST_JSON_NAME_VERSION_2_UNICODE "\xf0\x9f\x8c\x8b" +#define TEST_ICD_PATH_VERSION_2_UNICODE \ + "$<TARGET_FILE_DIR:test_icd_version_2>/" TEST_JSON_NAME_VERSION_2_UNICODE "$<TARGET_FILE_SUFFIX:test_icd_version_2>" + // assumes version 2 exports #define TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA "$<TARGET_FILE:test_icd_version_2_export_icd_gpdpa>" diff --git a/tests/framework/icd/CMakeLists.txt b/tests/framework/icd/CMakeLists.txt index 0ef56601d..9deb6d420 100644 --- a/tests/framework/icd/CMakeLists.txt +++ b/tests/framework/icd/CMakeLists.txt @@ -39,3 +39,9 @@ AddSharedLibrary(test_icd_version_2_export_icd_gpdpa DEF_FILE test_icd_2_gpdpa AddSharedLibrary(test_icd_version_6 DEF_FILE test_icd_6 SOURCES test_icd.cpp DEFINITIONS TEST_ICD_EXPORT_ICD_GPDPA=1 TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES=1 ${TEST_ICD_VERSION_2_DEFINES}) + +add_custom_command(TARGET test_icd_version_2 POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "$<TARGET_FILE:test_icd_version_2>" + "$<TARGET_FILE_DIR:test_icd_version_2>/🌋${CMAKE_SHARED_LIBRARY_SUFFIX}" +) diff --git a/tests/framework/test_util.cpp b/tests/framework/test_util.cpp index 6b796e7ce..1c27c0869 100644 --- a/tests/framework/test_util.cpp +++ b/tests/framework/test_util.cpp @@ -58,27 +58,24 @@ void print_error_message(LSTATUS status, const char* function_name, std::string } void set_env_var(std::string const& name, std::string const& value) { - BOOL ret = SetEnvironmentVariableA(name.c_str(), value.c_str()); + BOOL ret = SetEnvironmentVariableW(widen(name).c_str(), widen(value).c_str()); if (ret == 0) { - print_error_message(ERROR_SETENV_FAILED, "SetEnvironmentVariableA"); + print_error_message(ERROR_SETENV_FAILED, "SetEnvironmentVariableW"); } } -void remove_env_var(std::string const& name) { SetEnvironmentVariableA(name.c_str(), nullptr); } -#define ENV_VAR_BUFFER_SIZE 4096 +void remove_env_var(std::string const& name) { SetEnvironmentVariableW(widen(name).c_str(), nullptr); } std::string get_env_var(std::string const& name, bool report_failure) { - std::string value; - value.resize(ENV_VAR_BUFFER_SIZE); - DWORD ret = GetEnvironmentVariable(name.c_str(), &value[0], ENV_VAR_BUFFER_SIZE); - if (0 == ret) { - if (report_failure) print_error_message(ERROR_ENVVAR_NOT_FOUND, "GetEnvironmentVariable"); - return std::string(); - } else if (ENV_VAR_BUFFER_SIZE < ret) { - if (report_failure) std::cerr << "Not enough space to write environment variable" << name << "\n"; - return std::string(); - } else { - value.resize(ret); + std::wstring name_utf16 = widen(name); + DWORD value_size = GetEnvironmentVariableW(name_utf16.c_str(), nullptr, 0); + if (0 == value_size) { + if (report_failure) print_error_message(ERROR_ENVVAR_NOT_FOUND, "GetEnvironmentVariableW"); + return {}; } - return value; + std::wstring value(value_size, L'\0'); + if (GetEnvironmentVariableW(name_utf16.c_str(), &value[0], value_size) != value_size - 1) { + return {}; + } + return narrow(value); } #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) @@ -353,7 +350,7 @@ path& path::replace_filename(path const& replacement) { // internal implementation helper for per-platform creating & destroying folders int create_folder(path const& path) { #if defined(WIN32) - return _mkdir(path.c_str()); + return _wmkdir(widen(path.str()).c_str()); #else mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); return 0; @@ -362,25 +359,27 @@ int create_folder(path const& path) { int delete_folder_contents(path const& folder) { #if defined(WIN32) - if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(folder.c_str()) && GetLastError() == ERROR_FILE_NOT_FOUND) { + std::wstring folder_utf16 = widen(folder.str()); + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(folder_utf16.c_str()) && GetLastError() == ERROR_FILE_NOT_FOUND) { // nothing to delete return 0; } - std::string search_path = folder.str() + "/*.*"; + std::wstring search_path = folder_utf16 + L"/*.*"; std::string s_p = folder.str() + "/"; - WIN32_FIND_DATA fd; - HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &fd); + WIN32_FIND_DATAW fd; + HANDLE hFind = ::FindFirstFileW(search_path.c_str(), &fd); if (hFind != INVALID_HANDLE_VALUE) { do { + std::string file_name_utf8 = narrow(fd.cFileName); if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (!string_eq(fd.cFileName, ".") && !string_eq(fd.cFileName, "..")) { - delete_folder(s_p + fd.cFileName); + if (!string_eq(file_name_utf8.c_str(), ".") && !string_eq(file_name_utf8.c_str(), "..")) { + delete_folder(s_p + file_name_utf8); } } else { - std::string child_name = s_p + fd.cFileName; - DeleteFile(child_name.c_str()); + std::string child_name = s_p + file_name_utf8; + DeleteFileW(widen(child_name).c_str()); } - } while (::FindNextFile(hFind, &fd)); + } while (::FindNextFileW(hFind, &fd)); ::FindClose(hFind); } return 0; @@ -417,13 +416,19 @@ int delete_folder(path const& folder) { int ret = delete_folder_contents(folder); if (ret != 0) return ret; #if defined(WIN32) - _rmdir(folder.c_str()); + _wrmdir(widen(folder.str()).c_str()); return 0; #else return rmdir(folder.c_str()); #endif } +#if defined(WIN32) +std::wstring native_path(const std::string& utf8) { return widen(utf8); } +#else +const std::string& native_path(const std::string& utf8) { return utf8; } +#endif + FolderManager::FolderManager(path root_path, std::string name) : folder(root_path / name) { delete_folder_contents(folder); create_folder(folder); @@ -447,7 +452,7 @@ path FolderManager::write_manifest(std::string const& name, std::string const& c } else { files.emplace_back(name); } - auto file = std::ofstream(out_path.str(), std::ios_base::trunc | std::ios_base::out); + auto file = std::ofstream(native_path(out_path.str()), std::ios_base::trunc | std::ios_base::out); if (!file) { std::cerr << "Failed to create manifest " << name << " at " << out_path.str() << "\n"; return out_path; @@ -483,12 +488,12 @@ path FolderManager::copy_file(path const& file, std::string const& new_name) { } else { files.emplace_back(new_name); } - std::ifstream src(file.str(), std::ios::binary); + std::ifstream src(native_path(file.str()), std::ios::binary); if (!src) { std::cerr << "Failed to create file " << file.str() << " for copying from\n"; return new_filepath; } - std::ofstream dst(new_filepath.str(), std::ios::binary); + std::ofstream dst(native_path(new_filepath.str()), std::ios::binary); if (!dst) { std::cerr << "Failed to create file " << new_filepath.str() << " for copying to\n"; return new_filepath; @@ -672,3 +677,35 @@ VkDeviceCreateInfo* DeviceCreateInfo::get() noexcept { dev.pQueueCreateInfos = device_queue_infos.data(); return &dev; } + +#if defined(WIN32) +std::string narrow(const std::wstring& utf16) { + if (utf16.empty()) { + return {}; + } + int size = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), nullptr, 0, nullptr, nullptr); + if (size <= 0) { + return {}; + } + std::string utf8(size, '\0'); + if (WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), &utf8[0], size, nullptr, nullptr) != size) { + return {}; + } + return utf8; +} + +std::wstring widen(const std::string& utf8) { + if (utf8.empty()) { + return {}; + } + int size = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), nullptr, 0); + if (size <= 0) { + return {}; + } + std::wstring utf16(size, L'\0'); + if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), &utf16[0], size) != size) { + return {}; + } + return utf16; +} +#endif diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h index 376602414..d6fe16367 100644 --- a/tests/framework/test_util.h +++ b/tests/framework/test_util.h @@ -107,7 +107,6 @@ #if defined(WIN32) void set_env_var(std::string const& name, std::string const& value); void remove_env_var(std::string const& name); -#define ENV_VAR_BUFFER_SIZE 4096 std::string get_env_var(std::string const& name, bool report_failure = true); #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) @@ -243,13 +242,22 @@ inline void copy_string_to_char_array(std::string const& src, char* dst, size_t } #if defined(WIN32) +// Convert an UTF-16 wstring to an UTF-8 string +std::string narrow(const std::wstring &utf16); +// Convert an UTF-8 string to an UTF-16 wstring +std::wstring widen(const std::string &utf8); +#endif + +#if defined(WIN32) typedef HMODULE loader_platform_dl_handle; static loader_platform_dl_handle loader_platform_open_library(const char* lib_path) { + std::wstring lib_path_utf16 = widen(lib_path); // Try loading the library the original way first. - loader_platform_dl_handle lib_handle = LoadLibrary(lib_path); + loader_platform_dl_handle lib_handle = LoadLibraryW(lib_path_utf16.c_str()); if (lib_handle == nullptr && GetLastError() == ERROR_MOD_NOT_FOUND) { // If that failed, then try loading it with broader search folders. - lib_handle = LoadLibraryEx(lib_path, nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); + lib_handle = + LoadLibraryExW(lib_path_utf16.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); } return lib_handle; } diff --git a/tests/loader_envvar_tests.cpp b/tests/loader_envvar_tests.cpp index 59e5a7020..fb36aa32b 100644 --- a/tests/loader_envvar_tests.cpp +++ b/tests/loader_envvar_tests.cpp @@ -90,6 +90,19 @@ TEST(EnvVarICDOverrideSetup, version_2_negotiate_interface_version_and_icd_gipa) ASSERT_EQ(env.get_test_icd(0).called_vk_icd_gipa, CalledICDGIPA::vk_icd_gipa); } +// export vk_icdNegotiateLoaderICDInterfaceVersion and vk_icdGetInstanceProcAddr +TEST(EnvVarICDOverrideSetup, version_2_negotiate_interface_version_and_icd_gipa_unicode) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_UNICODE) + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_json_name(TEST_JSON_NAME_VERSION_2_UNICODE)); + + 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{}; |