1/* 2 * Copyright (c) 2021-2023 The Khronos Group Inc. 3 * Copyright (c) 2021-2023 Valve Corporation 4 * Copyright (c) 2021-2023 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and/or associated documentation files (the "Materials"), to 8 * deal in the Materials without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Materials, and to permit persons to whom the Materials are 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice(s) and this permission notice shall be included in 14 * all copies or substantial portions of the Materials. 15 * 16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 23 * USE OR OTHER DEALINGS IN THE MATERIALS. 24 * 25 * Author: Charles Giessen <charles@lunarg.com> 26 */ 27 28#include "test_environment.h" 29 30fs::path get_loader_path() { 31 auto loader_path = fs::path(FRAMEWORK_VULKAN_LIBRARY_PATH); 32 auto env_var_res = get_env_var("VK_LOADER_TEST_LOADER_PATH", false); 33 if (!env_var_res.empty()) { 34 loader_path = fs::path(env_var_res); 35 } 36 return loader_path; 37} 38 39void init_vulkan_functions(VulkanFunctions& funcs) { 40#if defined(APPLE_STATIC_LOADER) 41#define GPA(name) name 42#else 43#define GPA(name) funcs.loader.get_symbol(#name) 44#endif 45 46 // clang-format off 47 funcs.vkGetInstanceProcAddr = GPA(vkGetInstanceProcAddr); 48 funcs.vkEnumerateInstanceExtensionProperties = GPA(vkEnumerateInstanceExtensionProperties); 49 funcs.vkEnumerateInstanceLayerProperties = GPA(vkEnumerateInstanceLayerProperties); 50 funcs.vkEnumerateInstanceVersion = GPA(vkEnumerateInstanceVersion); 51 funcs.vkCreateInstance = GPA(vkCreateInstance); 52 funcs.vkDestroyInstance = GPA(vkDestroyInstance); 53 funcs.vkEnumeratePhysicalDevices = GPA(vkEnumeratePhysicalDevices); 54 funcs.vkEnumeratePhysicalDeviceGroups = GPA(vkEnumeratePhysicalDeviceGroups); 55 funcs.vkGetPhysicalDeviceFeatures = GPA(vkGetPhysicalDeviceFeatures); 56 funcs.vkGetPhysicalDeviceFeatures2 = GPA(vkGetPhysicalDeviceFeatures2); 57 funcs.vkGetPhysicalDeviceFormatProperties = GPA(vkGetPhysicalDeviceFormatProperties); 58 funcs.vkGetPhysicalDeviceFormatProperties2 = GPA(vkGetPhysicalDeviceFormatProperties2); 59 funcs.vkGetPhysicalDeviceImageFormatProperties = GPA(vkGetPhysicalDeviceImageFormatProperties); 60 funcs.vkGetPhysicalDeviceImageFormatProperties2 = GPA(vkGetPhysicalDeviceImageFormatProperties2); 61 funcs.vkGetPhysicalDeviceSparseImageFormatProperties = GPA(vkGetPhysicalDeviceSparseImageFormatProperties); 62 funcs.vkGetPhysicalDeviceSparseImageFormatProperties2 = GPA(vkGetPhysicalDeviceSparseImageFormatProperties2); 63 funcs.vkGetPhysicalDeviceProperties = GPA(vkGetPhysicalDeviceProperties); 64 funcs.vkGetPhysicalDeviceProperties2 = GPA(vkGetPhysicalDeviceProperties2); 65 funcs.vkGetPhysicalDeviceQueueFamilyProperties = GPA(vkGetPhysicalDeviceQueueFamilyProperties); 66 funcs.vkGetPhysicalDeviceQueueFamilyProperties2 = GPA(vkGetPhysicalDeviceQueueFamilyProperties2); 67 funcs.vkGetPhysicalDeviceMemoryProperties = GPA(vkGetPhysicalDeviceMemoryProperties); 68 funcs.vkGetPhysicalDeviceMemoryProperties2 = GPA(vkGetPhysicalDeviceMemoryProperties2); 69 funcs.vkGetPhysicalDeviceSurfaceSupportKHR = GPA(vkGetPhysicalDeviceSurfaceSupportKHR); 70 funcs.vkGetPhysicalDeviceSurfaceFormatsKHR = GPA(vkGetPhysicalDeviceSurfaceFormatsKHR); 71 funcs.vkGetPhysicalDeviceSurfacePresentModesKHR = GPA(vkGetPhysicalDeviceSurfacePresentModesKHR); 72 funcs.vkGetPhysicalDeviceSurfaceCapabilitiesKHR = GPA(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); 73 funcs.vkEnumerateDeviceExtensionProperties = GPA(vkEnumerateDeviceExtensionProperties); 74 funcs.vkEnumerateDeviceLayerProperties = GPA(vkEnumerateDeviceLayerProperties); 75 funcs.vkGetPhysicalDeviceExternalBufferProperties = GPA(vkGetPhysicalDeviceExternalBufferProperties); 76 funcs.vkGetPhysicalDeviceExternalFenceProperties = GPA(vkGetPhysicalDeviceExternalFenceProperties); 77 funcs.vkGetPhysicalDeviceExternalSemaphoreProperties = GPA(vkGetPhysicalDeviceExternalSemaphoreProperties); 78 79 funcs.vkDestroySurfaceKHR = GPA(vkDestroySurfaceKHR); 80 funcs.vkGetDeviceProcAddr = GPA(vkGetDeviceProcAddr); 81 funcs.vkCreateDevice = GPA(vkCreateDevice); 82 83 funcs.vkCreateHeadlessSurfaceEXT = GPA(vkCreateHeadlessSurfaceEXT); 84 funcs.vkCreateDisplayPlaneSurfaceKHR = GPA(vkCreateDisplayPlaneSurfaceKHR); 85 funcs.vkGetPhysicalDeviceDisplayPropertiesKHR = GPA(vkGetPhysicalDeviceDisplayPropertiesKHR); 86 funcs.vkGetPhysicalDeviceDisplayPlanePropertiesKHR = GPA(vkGetPhysicalDeviceDisplayPlanePropertiesKHR); 87 funcs.vkGetDisplayPlaneSupportedDisplaysKHR = GPA(vkGetDisplayPlaneSupportedDisplaysKHR); 88 funcs.vkGetDisplayModePropertiesKHR = GPA(vkGetDisplayModePropertiesKHR); 89 funcs.vkCreateDisplayModeKHR = GPA(vkCreateDisplayModeKHR); 90 funcs.vkGetDisplayPlaneCapabilitiesKHR = GPA(vkGetDisplayPlaneCapabilitiesKHR); 91 funcs.vkGetPhysicalDevicePresentRectanglesKHR = GPA(vkGetPhysicalDevicePresentRectanglesKHR); 92 funcs.vkGetPhysicalDeviceDisplayProperties2KHR = GPA(vkGetPhysicalDeviceDisplayProperties2KHR); 93 funcs.vkGetPhysicalDeviceDisplayPlaneProperties2KHR = GPA(vkGetPhysicalDeviceDisplayPlaneProperties2KHR); 94 funcs.vkGetDisplayModeProperties2KHR = GPA(vkGetDisplayModeProperties2KHR); 95 funcs.vkGetDisplayPlaneCapabilities2KHR = GPA(vkGetDisplayPlaneCapabilities2KHR); 96 funcs.vkGetPhysicalDeviceSurfaceCapabilities2KHR = GPA(vkGetPhysicalDeviceSurfaceCapabilities2KHR); 97 funcs.vkGetPhysicalDeviceSurfaceFormats2KHR = GPA(vkGetPhysicalDeviceSurfaceFormats2KHR); 98 99#if defined(VK_USE_PLATFORM_ANDROID_KHR) 100 funcs.vkCreateAndroidSurfaceKHR = GPA(vkCreateAndroidSurfaceKHR); 101#endif // VK_USE_PLATFORM_ANDROID_KHR 102#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) 103 funcs.vkCreateDirectFBSurfaceEXT = GPA(vkCreateDirectFBSurfaceEXT); 104 funcs.vkGetPhysicalDeviceDirectFBPresentationSupportEXT = GPA(vkGetPhysicalDeviceDirectFBPresentationSupportEXT); 105#endif // VK_USE_PLATFORM_DIRECTFB_EXT 106#if defined(VK_USE_PLATFORM_FUCHSIA) 107 funcs.vkCreateImagePipeSurfaceFUCHSIA = GPA(vkCreateImagePipeSurfaceFUCHSIA); 108#endif // VK_USE_PLATFORM_FUCHSIA 109#if defined(VK_USE_PLATFORM_GGP) 110 funcs.vkCreateStreamDescriptorSurfaceGGP = GPA(vkCreateStreamDescriptorSurfaceGGP); 111#endif // VK_USE_PLATFORM_GGP 112#if defined(VK_USE_PLATFORM_IOS_MVK) 113 funcs.vkCreateIOSSurfaceMVK = GPA(vkCreateIOSSurfaceMVK); 114#endif // VK_USE_PLATFORM_IOS_MVK 115#if defined(VK_USE_PLATFORM_MACOS_MVK) 116 funcs.vkCreateMacOSSurfaceMVK = GPA(vkCreateMacOSSurfaceMVK); 117#endif // VK_USE_PLATFORM_MACOS_MVK 118#if defined(VK_USE_PLATFORM_METAL_EXT) 119 funcs.vkCreateMetalSurfaceEXT = GPA(vkCreateMetalSurfaceEXT); 120#endif // VK_USE_PLATFORM_METAL_EXT 121#if defined(VK_USE_PLATFORM_SCREEN_QNX) 122 funcs.vkCreateScreenSurfaceQNX = GPA(vkCreateScreenSurfaceQNX); 123 funcs.vkGetPhysicalDeviceScreenPresentationSupportQNX = GPA(vkGetPhysicalDeviceScreenPresentationSupportQNX); 124#endif // VK_USE_PLATFORM_SCREEN_QNX 125#if defined(VK_USE_PLATFORM_WAYLAND_KHR) 126 funcs.vkCreateWaylandSurfaceKHR = GPA(vkCreateWaylandSurfaceKHR); 127 funcs.vkGetPhysicalDeviceWaylandPresentationSupportKHR = GPA(vkGetPhysicalDeviceWaylandPresentationSupportKHR); 128#endif // VK_USE_PLATFORM_WAYLAND_KHR 129#if defined(VK_USE_PLATFORM_XCB_KHR) 130 funcs.vkCreateXcbSurfaceKHR = GPA(vkCreateXcbSurfaceKHR); 131 funcs.vkGetPhysicalDeviceXcbPresentationSupportKHR = GPA(vkGetPhysicalDeviceXcbPresentationSupportKHR); 132#endif // VK_USE_PLATFORM_XCB_KHR 133#if defined(VK_USE_PLATFORM_XLIB_KHR) 134 funcs.vkCreateXlibSurfaceKHR = GPA(vkCreateXlibSurfaceKHR); 135 funcs.vkGetPhysicalDeviceXlibPresentationSupportKHR = GPA(vkGetPhysicalDeviceXlibPresentationSupportKHR); 136#endif // VK_USE_PLATFORM_XLIB_KHR 137#if defined(VK_USE_PLATFORM_WIN32_KHR) 138 funcs.vkCreateWin32SurfaceKHR = GPA(vkCreateWin32SurfaceKHR); 139 funcs.vkGetPhysicalDeviceWin32PresentationSupportKHR = GPA(vkGetPhysicalDeviceWin32PresentationSupportKHR); 140#endif // VK_USE_PLATFORM_WIN32_KHR 141 142 funcs.vkDestroyDevice = GPA(vkDestroyDevice); 143 funcs.vkGetDeviceQueue = GPA(vkGetDeviceQueue); 144#undef GPA 145 // clang-format on 146} 147 148#if defined(APPLE_STATIC_LOADER) 149VulkanFunctions::VulkanFunctions() { 150#else 151VulkanFunctions::VulkanFunctions() : loader(get_loader_path()) { 152#endif 153 init_vulkan_functions(*this); 154} 155 156DeviceFunctions::DeviceFunctions(const VulkanFunctions& vulkan_functions, VkDevice device) { 157 vkGetDeviceProcAddr = vulkan_functions.vkGetDeviceProcAddr; 158 vkDestroyDevice = load(device, "vkDestroyDevice"); 159 vkGetDeviceQueue = load(device, "vkGetDeviceQueue"); 160 vkCreateCommandPool = load(device, "vkCreateCommandPool"); 161 vkAllocateCommandBuffers = load(device, "vkAllocateCommandBuffers"); 162 vkDestroyCommandPool = load(device, "vkDestroyCommandPool"); 163 vkCreateSwapchainKHR = load(device, "vkCreateSwapchainKHR"); 164 vkGetSwapchainImagesKHR = load(device, "vkGetSwapchainImagesKHR"); 165 vkDestroySwapchainKHR = load(device, "vkDestroySwapchainKHR"); 166} 167 168InstWrapper::InstWrapper(VulkanFunctions& functions, VkAllocationCallbacks* callbacks) noexcept 169 : functions(&functions), callbacks(callbacks) {} 170InstWrapper::InstWrapper(VulkanFunctions& functions, VkInstance inst, VkAllocationCallbacks* callbacks) noexcept 171 : functions(&functions), inst(inst), callbacks(callbacks) {} 172InstWrapper::~InstWrapper() noexcept { 173 if (inst != VK_NULL_HANDLE) functions->vkDestroyInstance(inst, callbacks); 174} 175 176InstWrapper::InstWrapper(InstWrapper&& other) noexcept { 177 functions = other.functions; 178 inst = other.inst; 179 callbacks = other.callbacks; 180 create_info = other.create_info; 181 other.inst = VK_NULL_HANDLE; 182} 183InstWrapper& InstWrapper::operator=(InstWrapper&& other) noexcept { 184 functions->vkDestroyInstance(inst, callbacks); 185 functions = other.functions; 186 inst = other.inst; 187 callbacks = other.callbacks; 188 create_info = other.create_info; 189 other.inst = VK_NULL_HANDLE; 190 return *this; 191} 192 193void InstWrapper::CheckCreate(VkResult result_to_check) { 194 ASSERT_EQ(result_to_check, functions->vkCreateInstance(create_info.get(), callbacks, &inst)); 195} 196 197void InstWrapper::CheckCreateWithInfo(InstanceCreateInfo& create_info, VkResult result_to_check) { 198 ASSERT_EQ(result_to_check, functions->vkCreateInstance(create_info.get(), callbacks, &inst)); 199} 200 201std::vector<VkPhysicalDevice> InstWrapper::GetPhysDevs(uint32_t phys_dev_count, VkResult result_to_check) { 202 uint32_t physical_count = phys_dev_count; 203 std::vector<VkPhysicalDevice> physical_devices; 204 physical_devices.resize(phys_dev_count); 205 VkResult res = functions->vkEnumeratePhysicalDevices(inst, &physical_count, physical_devices.data()); 206 EXPECT_EQ(result_to_check, res); 207 return physical_devices; 208} 209 210std::vector<VkPhysicalDevice> InstWrapper::GetPhysDevs(VkResult result_to_check) { 211 uint32_t physical_count = 0; 212 VkResult res = functions->vkEnumeratePhysicalDevices(inst, &physical_count, nullptr); 213 EXPECT_EQ(result_to_check, res); 214 std::vector<VkPhysicalDevice> physical_devices; 215 physical_devices.resize(physical_count); 216 res = functions->vkEnumeratePhysicalDevices(inst, &physical_count, physical_devices.data()); 217 EXPECT_EQ(result_to_check, res); 218 return physical_devices; 219} 220 221VkPhysicalDevice InstWrapper::GetPhysDev(VkResult result_to_check) { 222 uint32_t physical_count = 1; 223 VkPhysicalDevice physical_device = VK_NULL_HANDLE; 224 VkResult res = this->functions->vkEnumeratePhysicalDevices(inst, &physical_count, &physical_device); 225 EXPECT_EQ(result_to_check, res); 226 return physical_device; 227} 228 229std::vector<VkLayerProperties> InstWrapper::GetActiveLayers(VkPhysicalDevice phys_dev, uint32_t expected_count) { 230 uint32_t count = 0; 231 VkResult res = functions->vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr); 232 EXPECT_EQ(VK_SUCCESS, res); 233 EXPECT_EQ(count, expected_count); 234 std::vector<VkLayerProperties> layer_props{count}; 235 res = functions->vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data()); 236 EXPECT_EQ(VK_SUCCESS, res); 237 EXPECT_EQ(count, expected_count); 238 return layer_props; 239} 240 241std::vector<VkExtensionProperties> InstWrapper::EnumerateDeviceExtensions(VkPhysicalDevice physical_device, 242 uint32_t expected_count) { 243 uint32_t count = 0; 244 VkResult res = functions->vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &count, nullptr); 245 EXPECT_EQ(VK_SUCCESS, res); 246 EXPECT_EQ(count, expected_count); 247 std::vector<VkExtensionProperties> extensions{count}; 248 res = functions->vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &count, extensions.data()); 249 EXPECT_EQ(VK_SUCCESS, res); 250 EXPECT_EQ(count, expected_count); 251 return extensions; 252} 253 254std::vector<VkExtensionProperties> InstWrapper::EnumerateLayerDeviceExtensions(VkPhysicalDevice physical_device, 255 const char* layer_name, uint32_t expected_count) { 256 uint32_t count = 0; 257 VkResult res = functions->vkEnumerateDeviceExtensionProperties(physical_device, layer_name, &count, nullptr); 258 EXPECT_EQ(VK_SUCCESS, res); 259 EXPECT_EQ(count, expected_count); 260 std::vector<VkExtensionProperties> extensions{count}; 261 res = functions->vkEnumerateDeviceExtensionProperties(physical_device, layer_name, &count, extensions.data()); 262 EXPECT_EQ(VK_SUCCESS, res); 263 EXPECT_EQ(count, expected_count); 264 return extensions; 265} 266 267DeviceWrapper::DeviceWrapper(InstWrapper& inst_wrapper, VkAllocationCallbacks* callbacks) noexcept 268 : functions(inst_wrapper.functions), callbacks(callbacks){}; 269DeviceWrapper::DeviceWrapper(VulkanFunctions& functions, VkDevice device, VkAllocationCallbacks* callbacks) noexcept 270 : functions(&functions), dev(device), callbacks(callbacks){}; 271DeviceWrapper::~DeviceWrapper() noexcept { functions->vkDestroyDevice(dev, callbacks); } 272 273DeviceWrapper::DeviceWrapper(DeviceWrapper&& other) noexcept { 274 functions = other.functions; 275 dev = other.dev; 276 callbacks = other.callbacks; 277 create_info = other.create_info; 278 other.dev = VK_NULL_HANDLE; 279} 280DeviceWrapper& DeviceWrapper::operator=(DeviceWrapper&& other) noexcept { 281 functions->vkDestroyDevice(dev, callbacks); 282 functions = other.functions; 283 dev = other.dev; 284 callbacks = other.callbacks; 285 create_info = other.create_info; 286 other.dev = VK_NULL_HANDLE; 287 return *this; 288} 289 290void DeviceWrapper::CheckCreate(VkPhysicalDevice phys_dev, VkResult result_to_check) { 291 ASSERT_EQ(result_to_check, functions->vkCreateDevice(phys_dev, create_info.get(), callbacks, &dev)); 292} 293 294VkResult CreateDebugUtilsMessenger(DebugUtilsWrapper& debug_utils) { 295 return debug_utils.vkCreateDebugUtilsMessengerEXT(debug_utils.inst, debug_utils.get(), debug_utils.callbacks, 296 &debug_utils.messenger); 297} 298 299void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsLogger& logger) { 300 create_info.add_extension("VK_EXT_debug_utils"); 301 create_info.instance_info.pNext = logger.get(); 302} 303void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsWrapper& wrapper) { 304 create_info.add_extension("VK_EXT_debug_utils"); 305 create_info.instance_info.pNext = wrapper.get(); 306} 307 308// Look through the event log. If you find a line containing the prefix we're interested in, look for the end of 309// line character, and then see if the postfix occurs in it as well. 310bool DebugUtilsLogger::find_prefix_then_postfix(const char* prefix, const char* postfix) const { 311 size_t new_start = 0; 312 size_t postfix_index = 0; 313 size_t next_eol = 0; 314 while ((new_start = returned_output.find(prefix, new_start)) != std::string::npos) { 315 next_eol = returned_output.find("\n", new_start); 316 if ((postfix_index = returned_output.find(postfix, new_start)) != std::string::npos) { 317 if (postfix_index < next_eol) { 318 return true; 319 } 320 } 321 new_start = next_eol + 1; 322 } 323 return false; 324} 325 326bool FindPrefixPostfixStringOnLine(DebugUtilsLogger const& env_log, const char* prefix, const char* postfix) { 327 return env_log.find_prefix_then_postfix(prefix, postfix); 328} 329 330PlatformShimWrapper::PlatformShimWrapper(std::vector<fs::FolderManager>* folders, const char* log_filter) noexcept 331 : loader_logging{"VK_LOADER_DEBUG"} { 332#if defined(WIN32) || defined(__APPLE__) 333 shim_library = LibraryWrapper(SHIM_LIBRARY_NAME); 334 PFN_get_platform_shim get_platform_shim_func = shim_library.get_symbol(GET_PLATFORM_SHIM_STR); 335 assert(get_platform_shim_func != NULL && "Must be able to get \"platform_shim\""); 336 platform_shim = get_platform_shim_func(folders); 337#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) 338 platform_shim = get_platform_shim(folders); 339#endif 340 platform_shim->reset(); 341 342 if (log_filter) { 343 loader_logging.set_new_value(log_filter); 344 } 345} 346 347PlatformShimWrapper::~PlatformShimWrapper() noexcept { platform_shim->reset(); } 348 349TestICDHandle::TestICDHandle() noexcept {} 350TestICDHandle::TestICDHandle(fs::path const& icd_path) noexcept : icd_library(icd_path) { 351 proc_addr_get_test_icd = icd_library.get_symbol(GET_TEST_ICD_FUNC_STR); 352 proc_addr_reset_icd = icd_library.get_symbol(RESET_ICD_FUNC_STR); 353} 354TestICD& TestICDHandle::get_test_icd() noexcept { 355 assert(proc_addr_get_test_icd != NULL && "symbol must be loaded before use"); 356 return *proc_addr_get_test_icd(); 357} 358TestICD& TestICDHandle::reset_icd() noexcept { 359 assert(proc_addr_reset_icd != NULL && "symbol must be loaded before use"); 360 return *proc_addr_reset_icd(); 361} 362fs::path TestICDHandle::get_icd_full_path() noexcept { return icd_library.lib_path; } 363fs::path TestICDHandle::get_icd_manifest_path() noexcept { return manifest_path; } 364fs::path TestICDHandle::get_shimmed_manifest_path() noexcept { return shimmed_manifest_path; } 365 366TestLayerHandle::TestLayerHandle() noexcept {} 367TestLayerHandle::TestLayerHandle(fs::path const& layer_path) noexcept : layer_library(layer_path) { 368 proc_addr_get_test_layer = layer_library.get_symbol(GET_TEST_LAYER_FUNC_STR); 369 proc_addr_reset_layer = layer_library.get_symbol(RESET_LAYER_FUNC_STR); 370} 371TestLayer& TestLayerHandle::get_test_layer() noexcept { 372 assert(proc_addr_get_test_layer != NULL && "symbol must be loaded before use"); 373 return *proc_addr_get_test_layer(); 374} 375TestLayer& TestLayerHandle::reset_layer() noexcept { 376 assert(proc_addr_reset_layer != NULL && "symbol must be loaded before use"); 377 return *proc_addr_reset_layer(); 378} 379fs::path TestLayerHandle::get_layer_full_path() noexcept { return layer_library.lib_path; } 380fs::path TestLayerHandle::get_layer_manifest_path() noexcept { return manifest_path; } 381fs::path TestLayerHandle::get_shimmed_manifest_path() noexcept { return shimmed_manifest_path; } 382 383FrameworkEnvironment::FrameworkEnvironment() noexcept : FrameworkEnvironment(FrameworkSettings{}) {} 384FrameworkEnvironment::FrameworkEnvironment(FrameworkSettings const& settings) noexcept 385 : settings(settings), platform_shim(&folders, settings.log_filter) { 386 // This order is important, it matches the enum ManifestLocation, used to index the folders vector 387 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("null_dir")); 388 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("icd_manifests")); 389 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("icd_env_vars_manifests")); 390 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_layer_manifests")); 391 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_env_var_layer_folder")); 392 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_add_env_var_layer_folder")); 393 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_layer_manifests")); 394 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("override_layer_manifests")); 395 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("app_package_manifests")); 396 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("macos_bundle")); 397 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("unsecured_location")); 398 folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("settings_location")); 399 400 platform_shim->redirect_all_paths(get_folder(ManifestLocation::null).location()); 401 if (settings.enable_default_search_paths) { 402 platform_shim->set_fake_path(ManifestCategory::icd, get_folder(ManifestLocation::driver).location()); 403 platform_shim->set_fake_path(ManifestCategory::explicit_layer, get_folder(ManifestLocation::explicit_layer).location()); 404 platform_shim->set_fake_path(ManifestCategory::implicit_layer, get_folder(ManifestLocation::implicit_layer).location()); 405#if COMMON_UNIX_PLATFORMS 406 auto home = get_env_var("HOME"); 407 auto unsecured_location = get_folder(ManifestLocation::unsecured_location).location(); 408 platform_shim->redirect_path(home + "/.local/share/vulkan/icd.d", unsecured_location); 409 platform_shim->redirect_path(home + "/.local/share/vulkan/implicit_layer.d", unsecured_location); 410 platform_shim->redirect_path(home + "/.local/share/vulkan/explicit_layer.d", unsecured_location); 411#endif 412 } 413#if COMMON_UNIX_PLATFORMS 414 if (settings.secure_loader_settings) { 415 platform_shim->redirect_path("/etc/vulkan/loader_settings.d", get_folder(ManifestLocation::settings_location).location()); 416 } else { 417 platform_shim->redirect_path(get_env_var("HOME") + "/.local/share/vulkan/loader_settings.d", 418 get_folder(ManifestLocation::settings_location).location()); 419 } 420#endif 421 422#if defined(__APPLE__) 423 // Necessary since bundles look in sub folders for manifests, not the test framework folder itself 424 auto bundle_location = get_folder(ManifestLocation::macos_bundle).location(); 425 platform_shim->redirect_path(bundle_location / "vulkan/icd.d", bundle_location); 426 platform_shim->redirect_path(bundle_location / "vulkan/explicit_layer.d", bundle_location); 427 platform_shim->redirect_path(bundle_location / "vulkan/implicit_layer.d", bundle_location); 428#endif 429 // only set the settings file if there are elements in the app_specific_settings vector 430 if (!settings.loader_settings.app_specific_settings.empty()) { 431 update_loader_settings(settings.loader_settings); 432 } 433} 434 435FrameworkEnvironment::~FrameworkEnvironment() { 436 // This is necessary to prevent the folder manager from using dead memory during destruction. 437 // What happens is that each folder manager tries to cleanup itself. Except, folders that were never called did not have their 438 // DirEntry array's filled out. So when that folder calls delete_folder, which calls readdir, the shim tries to order the files. 439 // Except, the list of files is in a object that is currently being destroyed. 440 platform_shim->is_during_destruction = true; 441} 442 443TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { 444 size_t cur_icd_index = icds.size(); 445 fs::FolderManager* folder = &get_folder(ManifestLocation::driver); 446 if (icd_details.discovery_type == ManifestDiscoveryType::env_var || 447 icd_details.discovery_type == ManifestDiscoveryType::add_env_var) { 448 folder = &get_folder(ManifestLocation::driver_env_var); 449 } 450 if (icd_details.discovery_type == ManifestDiscoveryType::windows_app_package) { 451 folder = &get_folder(ManifestLocation::windows_app_package); 452 } 453 if (icd_details.discovery_type == ManifestDiscoveryType::macos_bundle) { 454 folder = &get_folder(ManifestLocation::macos_bundle); 455 } 456 if (icd_details.discovery_type == ManifestDiscoveryType::unsecured_generic) { 457 folder = &get_folder(ManifestLocation::unsecured_location); 458 } 459 if (icd_details.discovery_type == ManifestDiscoveryType::null_dir || 460 icd_details.discovery_type == ManifestDiscoveryType::none) { 461 folder = &get_folder(ManifestLocation::null); 462 } 463 if (!icd_details.is_fake) { 464 fs::path new_driver_name = fs::path(icd_details.icd_manifest.lib_path).stem() + "_" + std::to_string(cur_icd_index) + 465 fs::path(icd_details.icd_manifest.lib_path).extension(); 466 467 auto new_driver_location = folder->copy_file(icd_details.icd_manifest.lib_path, new_driver_name.str()); 468 469#if COMMON_UNIX_PLATFORMS 470 if (icd_details.library_path_type == LibraryPathType::default_search_paths) { 471 platform_shim->redirect_dlopen_name(new_driver_name, new_driver_location); 472 } else if (icd_details.library_path_type == LibraryPathType::relative) { 473 platform_shim->redirect_dlopen_name(fs::path(SYSCONFDIR) / "vulkan" / "icd.d" / "." / new_driver_name, 474 new_driver_location); 475 } 476#endif 477#if defined(WIN32) 478 if (icd_details.library_path_type == LibraryPathType::default_search_paths) { 479 SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS); 480 AddDllDirectory(conver_str_to_wstr(new_driver_location.parent_path().str()).c_str()); 481 } 482#endif 483 icds.push_back(TestICDHandle(new_driver_location)); 484 icds.back().reset_icd(); 485 if (icd_details.library_path_type == LibraryPathType::relative) { 486 icd_details.icd_manifest.lib_path = fs::path(".") / new_driver_name; 487 } else if (icd_details.library_path_type == LibraryPathType::default_search_paths) { 488 icd_details.icd_manifest.lib_path = new_driver_name.str(); 489 } else { 490 icd_details.icd_manifest.lib_path = new_driver_location.str(); 491 } 492 } 493 if (icd_details.discovery_type != ManifestDiscoveryType::none) { 494 std::string full_json_name = icd_details.json_name; 495 if (!icd_details.disable_icd_inc) { 496 full_json_name += "_" + std::to_string(cur_icd_index); 497 } 498 full_json_name += ".json"; 499 icds.back().manifest_path = folder->write_manifest(full_json_name, icd_details.icd_manifest.get_manifest_str()); 500 icds.back().shimmed_manifest_path = icds.back().manifest_path; 501 switch (icd_details.discovery_type) { 502 default: 503 case (ManifestDiscoveryType::generic): 504 platform_shim->add_manifest(ManifestCategory::icd, icds.back().manifest_path); 505#if COMMON_UNIX_PLATFORMS 506 icds.back().shimmed_manifest_path = 507 platform_shim->query_default_redirect_path(ManifestCategory::icd) / full_json_name; 508#endif 509 break; 510 case (ManifestDiscoveryType::env_var): 511 if (icd_details.is_dir) { 512 env_var_vk_icd_filenames.add_to_list(folder->location().str()); 513 } else { 514 env_var_vk_icd_filenames.add_to_list((folder->location() / full_json_name).str()); 515 } 516 platform_shim->add_known_path(folder->location()); 517 break; 518 case (ManifestDiscoveryType::add_env_var): 519 if (icd_details.is_dir) { 520 add_env_var_vk_icd_filenames.add_to_list(folder->location().str()); 521 } else { 522 add_env_var_vk_icd_filenames.add_to_list((folder->location() / full_json_name).str()); 523 } 524 platform_shim->add_known_path(folder->location()); 525 break; 526 case (ManifestDiscoveryType::macos_bundle): 527 platform_shim->add_manifest(ManifestCategory::icd, icds.back().manifest_path); 528 break; 529 case (ManifestDiscoveryType::unsecured_generic): 530 platform_shim->add_unsecured_manifest(ManifestCategory::icd, icds.back().manifest_path); 531 break; 532 case (ManifestDiscoveryType::null_dir): 533 break; 534#if defined(_WIN32) 535 case (ManifestDiscoveryType::windows_app_package): 536 platform_shim->set_app_package_path(folder->location()); 537 break; 538#endif 539 } 540 } 541 return icds.back().get_test_icd(); 542} 543 544void FrameworkEnvironment::add_implicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept { 545 add_layer_impl(TestLayerDetails{layer_manifest, json_name}, ManifestCategory::implicit_layer); 546} 547void FrameworkEnvironment::add_explicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept { 548 add_layer_impl(TestLayerDetails{layer_manifest, json_name}, ManifestCategory::explicit_layer); 549} 550void FrameworkEnvironment::add_fake_implicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept { 551 add_layer_impl(TestLayerDetails{layer_manifest, json_name}.set_is_fake(true), ManifestCategory::implicit_layer); 552} 553void FrameworkEnvironment::add_fake_explicit_layer(ManifestLayer layer_manifest, const std::string& json_name) noexcept { 554 add_layer_impl(TestLayerDetails{layer_manifest, json_name}.set_is_fake(true), ManifestCategory::explicit_layer); 555} 556void FrameworkEnvironment::add_implicit_layer(TestLayerDetails layer_details) noexcept { 557 add_layer_impl(layer_details, ManifestCategory::implicit_layer); 558} 559void FrameworkEnvironment::add_explicit_layer(TestLayerDetails layer_details) noexcept { 560 add_layer_impl(layer_details, ManifestCategory::explicit_layer); 561} 562 563void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, ManifestCategory category) { 564 fs::FolderManager* fs_ptr = &get_folder(ManifestLocation::explicit_layer); 565 switch (layer_details.discovery_type) { 566 default: 567 case (ManifestDiscoveryType::generic): 568 if (category == ManifestCategory::implicit_layer) fs_ptr = &get_folder(ManifestLocation::implicit_layer); 569 break; 570 case (ManifestDiscoveryType::env_var): 571 fs_ptr = &get_folder(ManifestLocation::explicit_layer_env_var); 572 if (layer_details.is_dir) { 573 env_var_vk_layer_paths.add_to_list(fs_ptr->location().str()); 574 } else { 575 env_var_vk_layer_paths.add_to_list((fs_ptr->location() / layer_details.json_name).str()); 576 } 577 platform_shim->add_known_path(fs_ptr->location()); 578 break; 579 case (ManifestDiscoveryType::add_env_var): 580 fs_ptr = &get_folder(ManifestLocation::explicit_layer_add_env_var); 581 if (layer_details.is_dir) { 582 add_env_var_vk_layer_paths.add_to_list(fs_ptr->location().str()); 583 } else { 584 add_env_var_vk_layer_paths.add_to_list((fs_ptr->location() / layer_details.json_name).str()); 585 } 586 platform_shim->add_known_path(fs_ptr->location()); 587 break; 588 case (ManifestDiscoveryType::override_folder): 589 fs_ptr = &get_folder(ManifestLocation::override_layer); 590 break; 591 case (ManifestDiscoveryType::macos_bundle): 592 fs_ptr = &(get_folder(ManifestLocation::macos_bundle)); 593 break; 594 case (ManifestDiscoveryType::unsecured_generic): 595 fs_ptr = &(get_folder(ManifestLocation::unsecured_location)); 596 break; 597 case (ManifestDiscoveryType::none): 598 case (ManifestDiscoveryType::null_dir): 599 fs_ptr = &(get_folder(ManifestLocation::null)); 600 break; 601 } 602 auto& folder = *fs_ptr; 603 size_t new_layers_start = layers.size(); 604 for (auto& layer : layer_details.layer_manifest.layers) { 605 if (!layer.lib_path.str().empty()) { 606 fs::path layer_binary_name = 607 layer.lib_path.filename().stem() + "_" + std::to_string(layers.size()) + layer.lib_path.filename().extension(); 608 609 auto new_layer_location = folder.copy_file(layer.lib_path, layer_binary_name.str()); 610 611#if COMMON_UNIX_PLATFORMS 612 if (layer_details.library_path_type == LibraryPathType::default_search_paths) { 613 platform_shim->redirect_dlopen_name(layer_binary_name, new_layer_location); 614 } 615 if (layer_details.library_path_type == LibraryPathType::relative) { 616 platform_shim->redirect_dlopen_name( 617 fs::path(SYSCONFDIR) / "vulkan" / category_path_name(category) / "." / layer_binary_name, new_layer_location); 618 } 619#endif 620#if defined(WIN32) 621 if (layer_details.library_path_type == LibraryPathType::default_search_paths) { 622 SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS); 623 AddDllDirectory(conver_str_to_wstr(new_layer_location.parent_path().str()).c_str()); 624 } 625#endif 626 627 // Don't load the layer binary if using any of the wrap objects layers, since it doesn't export the same interface 628 // functions 629 if (!layer_details.is_fake && 630 layer.lib_path.stem().str().find(fs::path(TEST_LAYER_WRAP_OBJECTS).stem().str()) == std::string::npos) { 631 layers.push_back(TestLayerHandle(new_layer_location)); 632 layers.back().reset_layer(); 633 } 634 if (layer_details.library_path_type == LibraryPathType::relative) { 635 layer.lib_path = fs::path(".") / layer_binary_name; 636 } else if (layer_details.library_path_type == LibraryPathType::default_search_paths) { 637 layer.lib_path = layer_binary_name; 638 } else { 639 layer.lib_path = new_layer_location; 640 } 641 } 642 } 643 if (layer_details.discovery_type != ManifestDiscoveryType::none) { 644 // Write a manifest file to a folder as long as the discovery type isn't none 645 auto layer_manifest_loc = folder.write_manifest(layer_details.json_name, layer_details.layer_manifest.get_manifest_str()); 646 // only add the manifest to the registry if its a generic location (as if it was installed) - both system and user local 647 if (layer_details.discovery_type == ManifestDiscoveryType::generic) { 648 platform_shim->add_manifest(category, layer_manifest_loc); 649 } 650 if (layer_details.discovery_type == ManifestDiscoveryType::unsecured_generic) { 651 platform_shim->add_unsecured_manifest(category, layer_manifest_loc); 652 } 653 for (size_t i = new_layers_start; i < layers.size(); i++) { 654 layers.at(i).manifest_path = layer_manifest_loc; 655 layers.at(i).shimmed_manifest_path = layer_manifest_loc; 656#if COMMON_UNIX_PLATFORMS 657 if (layer_details.discovery_type == ManifestDiscoveryType::generic) { 658 layers.at(i).shimmed_manifest_path = platform_shim->query_default_redirect_path(category) / layer_details.json_name; 659 } 660#endif 661 } 662 } 663} 664 665std::string get_loader_settings_file_contents(const LoaderSettings& loader_settings) noexcept { 666 JsonWriter writer; 667 writer.StartObject(); 668 writer.AddKeyedString("file_format_version", loader_settings.file_format_version.get_version_str()); 669 bool one_setting_file = true; 670 if (loader_settings.app_specific_settings.size() > 1) { 671 writer.StartKeyedArray("settings_array"); 672 one_setting_file = false; 673 } 674 for (const auto& setting : loader_settings.app_specific_settings) { 675 if (one_setting_file) { 676 writer.StartKeyedObject("settings"); 677 } else { 678 writer.StartObject(); 679 } 680 if (!setting.app_keys.empty()) { 681 writer.StartKeyedArray("app_keys"); 682 for (const auto& app_key : setting.app_keys) { 683 writer.AddString(app_key); 684 } 685 writer.EndArray(); 686 } 687 if (!setting.layer_configurations.empty()) { 688 writer.StartKeyedArray("layers"); 689 for (const auto& config : setting.layer_configurations) { 690 writer.StartObject(); 691 writer.AddKeyedString("name", config.name); 692 writer.AddKeyedString("path", fs::fixup_backslashes_in_path(config.path)); 693 writer.AddKeyedString("control", config.control); 694 writer.AddKeyedBool("treat_as_implicit_manifest", config.treat_as_implicit_manifest); 695 writer.EndObject(); 696 } 697 writer.EndArray(); 698 } 699 if (!setting.stderr_log.empty()) { 700 writer.StartKeyedArray("stderr_log"); 701 for (const auto& filter : setting.stderr_log) { 702 writer.AddString(filter); 703 } 704 writer.EndArray(); 705 } 706 if (!setting.log_configurations.empty()) { 707 writer.StartKeyedArray("log_locations"); 708 for (const auto& config : setting.log_configurations) { 709 writer.StartObject(); 710 writer.StartKeyedArray("destinations"); 711 for (const auto& dest : config.destinations) { 712 writer.AddString(dest); 713 } 714 writer.EndArray(); 715 writer.StartKeyedArray("filter"); 716 for (const auto& filter : config.filters) { 717 writer.AddString(filter); 718 } 719 writer.EndArray(); 720 writer.EndObject(); 721 } 722 writer.EndArray(); 723 } 724 writer.EndObject(); 725 } 726 if (!one_setting_file) { 727 writer.EndArray(); 728 } 729 730 writer.EndObject(); 731 return writer.output; 732} 733void FrameworkEnvironment::write_settings_file(std::string const& file_contents) { 734 auto out_path = get_folder(ManifestLocation::settings_location).write_manifest("vk_loader_settings.json", file_contents); 735#if defined(WIN32) 736 platform_shim->hkey_current_user_settings.clear(); 737 platform_shim->hkey_local_machine_settings.clear(); 738#endif 739 if (settings.secure_loader_settings) 740 platform_shim->add_manifest(ManifestCategory::settings, out_path); 741 else 742 platform_shim->add_unsecured_manifest(ManifestCategory::settings, out_path); 743} 744void FrameworkEnvironment::update_loader_settings(const LoaderSettings& settings) noexcept { 745 write_settings_file(get_loader_settings_file_contents(settings)); 746} 747void FrameworkEnvironment::remove_loader_settings() { 748 get_folder(ManifestLocation::settings_location).remove("vk_loader_settings.json"); 749} 750 751TestICD& FrameworkEnvironment::get_test_icd(size_t index) noexcept { return icds[index].get_test_icd(); } 752TestICD& FrameworkEnvironment::reset_icd(size_t index) noexcept { return icds[index].reset_icd(); } 753fs::path FrameworkEnvironment::get_test_icd_path(size_t index) noexcept { return icds[index].get_icd_full_path(); } 754fs::path FrameworkEnvironment::get_icd_manifest_path(size_t index) noexcept { return icds[index].get_icd_manifest_path(); } 755fs::path FrameworkEnvironment::get_shimmed_icd_manifest_path(size_t index) noexcept { 756 return icds[index].get_shimmed_manifest_path(); 757} 758 759TestLayer& FrameworkEnvironment::get_test_layer(size_t index) noexcept { return layers[index].get_test_layer(); } 760TestLayer& FrameworkEnvironment::reset_layer(size_t index) noexcept { return layers[index].reset_layer(); } 761fs::path FrameworkEnvironment::get_test_layer_path(size_t index) noexcept { return layers[index].get_layer_full_path(); } 762fs::path FrameworkEnvironment::get_layer_manifest_path(size_t index) noexcept { return layers[index].get_layer_manifest_path(); } 763fs::path FrameworkEnvironment::get_shimmed_layer_manifest_path(size_t index) noexcept { 764 return layers[index].get_shimmed_manifest_path(); 765} 766 767fs::FolderManager& FrameworkEnvironment::get_folder(ManifestLocation location) noexcept { 768 // index it directly using the enum location since they will always be in that order 769 return folders.at(static_cast<size_t>(location)); 770} 771fs::FolderManager const& FrameworkEnvironment::get_folder(ManifestLocation location) const noexcept { 772 return folders.at(static_cast<size_t>(location)); 773} 774#if defined(__APPLE__) 775void FrameworkEnvironment::setup_macos_bundle() noexcept { 776 platform_shim->bundle_contents = get_folder(ManifestLocation::macos_bundle).location().str(); 777} 778#endif 779 780std::vector<VkExtensionProperties> FrameworkEnvironment::GetInstanceExtensions(uint32_t expected_count, const char* layer_name) { 781 uint32_t count = 0; 782 VkResult res = vulkan_functions.vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr); 783 EXPECT_EQ(VK_SUCCESS, res); 784 EXPECT_EQ(count, expected_count); 785 std::vector<VkExtensionProperties> extension_props{count}; 786 res = vulkan_functions.vkEnumerateInstanceExtensionProperties(layer_name, &count, extension_props.data()); 787 EXPECT_EQ(VK_SUCCESS, res); 788 EXPECT_EQ(count, expected_count); 789 return extension_props; 790} 791std::vector<VkLayerProperties> FrameworkEnvironment::GetLayerProperties(uint32_t expected_count) { 792 uint32_t count = 0; 793 VkResult res = vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr); 794 EXPECT_EQ(VK_SUCCESS, res); 795 EXPECT_EQ(count, expected_count); 796 std::vector<VkLayerProperties> layer_props{count}; 797 res = vulkan_functions.vkEnumerateInstanceLayerProperties(&count, layer_props.data()); 798 EXPECT_EQ(VK_SUCCESS, res); 799 EXPECT_EQ(count, expected_count); 800 return layer_props; 801} 802 803template <typename CreationFunc, typename CreateInfo> 804VkResult create_surface_helper(VulkanFunctions* functions, VkInstance inst, VkSurfaceKHR& surface, const char* load_func_name) { 805 CreationFunc pfn_CreateSurface = functions->load(inst, load_func_name); 806 if (!pfn_CreateSurface) return VK_ERROR_EXTENSION_NOT_PRESENT; 807 CreateInfo surf_create_info{}; 808 return pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface); 809} 810VkResult create_surface(VulkanFunctions* functions, VkInstance inst, VkSurfaceKHR& surface, 811 [[maybe_unused]] const char* api_selection) { 812#if defined(VK_USE_PLATFORM_ANDROID_KHR) 813 return create_surface_helper<PFN_vkCreateAndroidSurfaceKHR, VkAndroidSurfaceCreateInfoKHR>(functions, inst, surface, 814 "vkCreateAndroidSurfaceKHR"); 815#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) 816 return create_surface_helper<PFN_vkCreateDirectFBSurfaceEXT, VkDirectFBSurfaceCreateInfoEXT>(functions, inst, surface, 817 "vkCreateDirectFBSurfaceEXT"); 818#elif defined(VK_USE_PLATFORM_FUCHSIA) 819 return create_surface_helper<PFN_vkCreateImagePipeSurfaceFUCHSIA, VkImagePipeSurfaceCreateInfoFUCHSIA>( 820 functions, inst, surface, "vkCreateImagePipeSurfaceFUCHSIA"); 821#elif defined(VK_USE_PLATFORM_GGP) 822 return create_surface_helper<PFN__vkCreateStreamDescriptorSurfaceGGP, VkStreamDescriptorSurfaceCreateInfoGGP>( 823 functions, inst, surface, "vkCreateStreamDescriptorSurfaceGGP"); 824#elif defined(VK_USE_PLATFORM_IOS_MVK) 825 return create_surface_helper<PFN_vkCreateIOSSurfaceMVK, VkIOSSurfaceCreateInfoMVK>(functions, inst, surface, 826 "vkCreateIOSSurfaceMVK"); 827#elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) 828#if defined(VK_USE_PLATFORM_MACOS_MVK) 829 if (api_selection != nullptr && string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK")) 830 return create_surface_helper<PFN_vkCreateMacOSSurfaceMVK, VkMacOSSurfaceCreateInfoMVK>(functions, inst, surface, 831 "vkCreateMacOSSurfaceMVK"); 832#endif 833#if defined(VK_USE_PLATFORM_METAL_EXT) 834 if (api_selection == nullptr || (api_selection != nullptr && string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT"))) 835 return create_surface_helper<PFN_vkCreateMetalSurfaceEXT, VkMetalSurfaceCreateInfoEXT>(functions, inst, surface, 836 "vkCreateMetalSurfaceEXT"); 837#endif 838 return VK_ERROR_NOT_PERMITTED_KHR; 839#elif defined(VK_USE_PLATFORM_SCREEN_QNX) 840 return create_surface_helper<PFN_vkCreateScreenSurfaceQNX, VkScreenSurfaceCreateInfoQNX>(functions, inst, surface, 841 "vkCreateScreenSurfaceQNX"); 842#elif defined(VK_USE_PLATFORM_VI_NN) 843 return create_surface_helper<PFN_vkCreateViSurfaceNN, VkViSurfaceCreateInfoNN>(functions, inst, surface, "vkCreateViSurfaceNN"); 844#elif defined(VK_USE_PLATFORM_WIN32_KHR) 845 return create_surface_helper<PFN_vkCreateWin32SurfaceKHR, VkWin32SurfaceCreateInfoKHR>(functions, inst, surface, 846 "vkCreateWin32SurfaceKHR"); 847#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR) 848#if defined(VK_USE_PLATFORM_XLIB_KHR) 849 if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR")) 850 return create_surface_helper<PFN_vkCreateXlibSurfaceKHR, VkXlibSurfaceCreateInfoKHR>(functions, inst, surface, 851 "vkCreateXlibSurfaceKHR"); 852#endif 853#if defined(VK_USE_PLATFORM_WAYLAND_KHR) 854 if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR")) 855 return create_surface_helper<PFN_vkCreateWaylandSurfaceKHR, VkWaylandSurfaceCreateInfoKHR>(functions, inst, surface, 856 "vkCreateWaylandSurfaceKHR"); 857#endif 858#if defined(VK_USE_PLATFORM_XCB_KHR) 859 if (api_selection == nullptr || string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR")) 860 return create_surface_helper<PFN_vkCreateXcbSurfaceKHR, VkXcbSurfaceCreateInfoKHR>(functions, inst, surface, 861 "vkCreateXcbSurfaceKHR"); 862#endif 863 return VK_ERROR_NOT_PERMITTED_KHR; 864#else 865 return create_surface_helper<PFN_vkCreateDisplayPlaneSurfaceKHR, VkDisplaySurfaceCreateInfoKHR>( 866 functions, inst, surface, "vkCreateDisplayPlaneSurfaceKHR"); 867#endif 868} 869VkResult create_surface(InstWrapper& inst, VkSurfaceKHR& surface, const char* api_selection) { 870 return create_surface(inst.functions, inst.inst, surface, api_selection); 871} 872 873extern "C" { 874void __ubsan_on_report() { FAIL() << "Encountered an undefined behavior sanitizer error"; } 875void __asan_on_error() { FAIL() << "Encountered an address sanitizer error"; } 876void __tsan_on_report() { FAIL() << "Encountered a thread sanitizer error"; } 877} // extern "C" 878