diff options
-rw-r--r-- | loader/loader.c | 2 | ||||
-rw-r--r-- | loader/trampoline.c | 6 | ||||
-rw-r--r-- | tests/framework/shim/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/framework/shim/shim.h | 4 | ||||
-rw-r--r-- | tests/framework/shim/shim_common.cpp | 13 | ||||
-rw-r--r-- | tests/framework/shim/unix_shim.cpp | 36 | ||||
-rw-r--r-- | tests/framework/test_environment.cpp | 23 | ||||
-rw-r--r-- | tests/framework/test_environment.h | 7 | ||||
-rw-r--r-- | tests/framework/test_util.h | 2 | ||||
-rw-r--r-- | tests/loader_regression_tests.cpp | 48 |
10 files changed, 130 insertions, 12 deletions
diff --git a/loader/loader.c b/loader/loader.c index c1af4a31..fff5ca9b 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -127,7 +127,7 @@ loader_api_version loader_combine_version(uint32_t major, uint32_t minor, uint32 bool loader_check_version_meets_required(loader_api_version required, loader_api_version version) { // major version is satisfied return (version.major > required.major) || - // major version is equal, minor version is patch version is gerater to minimum minor + // major version is equal, minor version is patch version is greater to minimum minor (version.major == required.major && version.minor > required.minor) || // major and minor version are equal, patch version is greater or equal to minimum patch (version.major == required.major && version.minor == required.minor && version.patch >= required.patch); diff --git a/loader/trampoline.c b/loader/trampoline.c index 9066a087..740898ff 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -38,7 +38,7 @@ // Trampoline entrypoints are in this file for core Vulkan commands -/* vkGetInstanceProcAddr: Get global level or instance level entrypoint addressess. +/* vkGetInstanceProcAddr: Get global level or instance level entrypoint addresses. * @param instance * @param pName * @return @@ -55,7 +55,7 @@ * * Note: * Vulkan header updated 1.2.193 changed the behavior of vkGetInstanceProcAddr for global entrypoints. They used to always be - * returned regardless of the value of the instance paramtere. The spec was amended in this version to only allow querying global + * returned regardless of the value of the instance parameter. The spec was amended in this version to only allow querying global * level entrypoints with a NULL instance. However, as to not break old applications, the new behavior is only applied if the * instance passed in is both valid and minor version is greater than 1.2, which was when this change in behavior occurred. Only * instances with a newer version will get the new behavior. @@ -2131,7 +2131,7 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandB const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer); if (NULL == disp) { loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, - "vkCmdCopyImage: Invalid commandBuffer [VUID-vkCmdCopyImage-devcommandBufferice-parameter]"); + "vkCmdCopyImage: Invalid commandBuffer [VUID-vkCmdCopyImage-commandBuffer-parameter]"); abort(); /* Intentionally fail so user can correct issue. */ } diff --git a/tests/framework/shim/CMakeLists.txt b/tests/framework/shim/CMakeLists.txt index 82c2573f..919dd362 100644 --- a/tests/framework/shim/CMakeLists.txt +++ b/tests/framework/shim/CMakeLists.txt @@ -31,6 +31,7 @@ if (WIN32) elseif(UNIX) if(APPLE) add_library(shim-library SHARED unix_shim.cpp) + target_link_libraries(shim-library PRIVATE "-framework CoreFoundation") else() add_library(shim-library STATIC unix_shim.cpp) endif() diff --git a/tests/framework/shim/shim.h b/tests/framework/shim/shim.h index b619465e..44d54dd1 100644 --- a/tests/framework/shim/shim.h +++ b/tests/framework/shim/shim.h @@ -194,6 +194,10 @@ struct PlatformShim { bool use_fake_elevation = false; std::vector<DirEntry> dir_entries; + + #if defined(__APPLE__) + std::string bundle_contents; + #endif #endif }; diff --git a/tests/framework/shim/shim_common.cpp b/tests/framework/shim/shim_common.cpp index 2c16a8a5..02f71b85 100644 --- a/tests/framework/shim/shim_common.cpp +++ b/tests/framework/shim/shim_common.cpp @@ -180,10 +180,15 @@ void PlatformShim::redirect_category(fs::path const& new_path, ManifestCategory paths.push_back((home / ".config").str()); paths.push_back((home / ".local/share").str()); } - parse_and_add_env_var_override(paths, get_env_var("XDG_CONFIG_DIRS")); - parse_and_add_env_var_override(paths, get_env_var("XDG_CONFIG_HOME")); - parse_and_add_env_var_override(paths, get_env_var("XDG_DATA_DIRS")); - parse_and_add_env_var_override(paths, get_env_var("XDG_DATA_HOME")); + // Don't report errors on apple - these env-vars are not suppose to be defined + bool report_errors = true; +#if defined(__APPLE__) + report_errors = false; +#endif + parse_and_add_env_var_override(paths, get_env_var("XDG_CONFIG_DIRS", report_errors)); + parse_and_add_env_var_override(paths, get_env_var("XDG_CONFIG_HOME", report_errors)); + parse_and_add_env_var_override(paths, get_env_var("XDG_DATA_DIRS", report_errors)); + parse_and_add_env_var_override(paths, get_env_var("XDG_DATA_HOME", report_errors)); if (category == ManifestCategory::explicit_layer) { parse_and_add_env_var_override(paths, get_env_var("VK_LAYER_PATH", false)); // don't report failure } diff --git a/tests/framework/shim/unix_shim.cpp b/tests/framework/shim/unix_shim.cpp index e930293b..1f039420 100644 --- a/tests/framework/shim/unix_shim.cpp +++ b/tests/framework/shim/unix_shim.cpp @@ -27,6 +27,12 @@ #include "shim.h" +#include <algorithm> + +#if defined(__APPLE__) +#include <CoreFoundation/CoreFoundation.h> +#endif + static PlatformShim platform_shim; extern "C" { #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) @@ -270,6 +276,29 @@ FRAMEWORK_EXPORT char* __SECURE_GETENV_FUNC_NAME(const char* name) { } #endif +#if defined(__APPLE__) +FRAMEWORK_EXPORT CFBundleRef my_CFBundleGetMainBundle() { + static CFBundleRef global_bundle{}; + return reinterpret_cast<CFBundleRef>(&global_bundle); +} +FRAMEWORK_EXPORT CFURLRef my_CFBundleCopyResourcesDirectoryURL(CFBundleRef bundle) { + static CFURLRef global_url{}; + return reinterpret_cast<CFURLRef>(&global_url); +} +FRAMEWORK_EXPORT Boolean my_CFURLGetFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBase, UInt8* buffer, + CFIndex maxBufLen) { + if (!platform_shim.bundle_contents.empty()) { + size_t copy_len = platform_shim.bundle_contents.size(); + if (copy_len > maxBufLen) { + copy_len = maxBufLen; + } + strncpy(reinterpret_cast<char*>(buffer), platform_shim.bundle_contents.c_str(), copy_len); + return TRUE; + } + return FALSE; +} +#endif + /* Shiming functions on apple is limited by the linker prefering to not use functions in the * executable in loaded dylibs. By adding an interposer, we redirect the linker to use our * version of the function over the real one, thus shimming the system function. @@ -299,5 +328,12 @@ __attribute__((used)) static Interposer _interpose_secure_getenv MACOS_ATTRIB = __attribute__((used)) static Interposer _interpose__secure_getenv MACOS_ATTRIB = {VOIDP_CAST(my__secure_getenv), VOIDP_CAST(__secure_getenv)}; #endif +__attribute__((used)) static Interposer _interpose_CFBundleGetMainBundle MACOS_ATTRIB = {VOIDP_CAST(my_CFBundleGetMainBundle), + VOIDP_CAST(CFBundleGetMainBundle)}; +__attribute__((used)) static Interposer _interpose_CFBundleCopyResourcesDirectoryURL MACOS_ATTRIB = { + VOIDP_CAST(my_CFBundleCopyResourcesDirectoryURL), VOIDP_CAST(CFBundleCopyResourcesDirectoryURL)}; +__attribute__((used)) static Interposer _interpose_CFURLGetFileSystemRepresentation MACOS_ATTRIB = { + VOIDP_CAST(my_CFURLGetFileSystemRepresentation), VOIDP_CAST(CFURLGetFileSystemRepresentation)}; + #endif } // extern "C" diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index 308230e6..079bbcd9 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -360,6 +360,7 @@ FrameworkEnvironment::FrameworkEnvironment(bool enable_log, bool set_default_sea folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_layer_manifests")); folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("override_layer_manifests")); folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("app_package_manifests")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("macos_bundle")); platform_shim->redirect_all_paths(get_folder(ManifestLocation::null).location()); if (set_default_search_paths) { @@ -367,6 +368,13 @@ FrameworkEnvironment::FrameworkEnvironment(bool enable_log, bool set_default_sea platform_shim->set_path(ManifestCategory::explicit_layer, get_folder(ManifestLocation::explicit_layer).location()); platform_shim->set_path(ManifestCategory::implicit_layer, get_folder(ManifestLocation::implicit_layer).location()); } +#if defined(__APPLE__) + // Necessary since bundles look in sub folders for manifests, not the test framework folder itself + auto bundle_location = get_folder(ManifestLocation::macos_bundle).location(); + platform_shim->redirect_path(bundle_location / "vulkan/icd.d", bundle_location); + platform_shim->redirect_path(bundle_location / "vulkan/explicit_layer.d", bundle_location); + platform_shim->redirect_path(bundle_location / "vulkan/implicit_layer.d", bundle_location); +#endif } void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { @@ -379,6 +387,9 @@ void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { if (icd_details.discovery_type == ManifestDiscoveryType::windows_app_package) { folder = &get_folder(ManifestLocation::windows_app_package); } + if (icd_details.discovery_type == ManifestDiscoveryType::macos_bundle) { + folder = &get_folder(ManifestLocation::macos_bundle); + } if (!icd_details.is_fake) { fs::path new_driver_name = fs::path(icd_details.icd_manifest.lib_path).stem() + "_" + std::to_string(cur_icd_index) + fs::path(icd_details.icd_manifest.lib_path).extension(); @@ -415,6 +426,8 @@ void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { add_env_var_vk_icd_filenames += (folder->location() / full_json_name).str(); set_env_var("VK_ADD_DRIVER_FILES", add_env_var_vk_icd_filenames); break; + case (ManifestDiscoveryType::macos_bundle): + platform_shim->add_manifest(ManifestCategory::icd, icds.back().manifest_path); case (ManifestDiscoveryType::none): break; #ifdef _WIN32 @@ -456,7 +469,7 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife if (!env_var_vk_layer_paths.empty()) { env_var_vk_layer_paths += OS_ENV_VAR_LIST_SEPARATOR; } - if(layer_details.is_dir) { + if (layer_details.is_dir) { env_var_vk_layer_paths += fs_ptr->location().str(); } else { env_var_vk_layer_paths += fs_ptr->location().str() + OS_ENV_VAR_LIST_SEPARATOR + layer_details.json_name; @@ -475,6 +488,9 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife case (ManifestDiscoveryType::override_folder): fs_ptr = &get_folder(ManifestLocation::override_layer); break; + case (ManifestDiscoveryType::macos_bundle): + fs_ptr = &(get_folder(ManifestLocation::macos_bundle)); + break; case (ManifestDiscoveryType::none): break; } @@ -520,6 +536,11 @@ fs::FolderManager& FrameworkEnvironment::get_folder(ManifestLocation location) n // index it directly using the enum location since they will always be in that order return folders.at(static_cast<size_t>(location)); } +#if defined(__APPLE__) +void FrameworkEnvironment::setup_macos_bundle() noexcept { + platform_shim->bundle_contents = get_folder(ManifestLocation::macos_bundle).location().str(); +} +#endif const char* get_platform_wsi_extension(const char* api_selection) { #if defined(VK_USE_PLATFORM_ANDROID_KHR) return "VK_KHR_android_surface"; diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index bcc39bfe..a04c9e2e 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -456,6 +456,7 @@ enum class ManifestDiscoveryType { add_env_var, // use the corresponding add-env-var for it override_folder, // add to a special folder for the override layer to use windows_app_package, // let the app package search find it + macos_bundle, // place it in a location only accessible to macos bundles }; struct TestICDDetails { @@ -490,6 +491,7 @@ enum class ManifestLocation { implicit_layer = 6, override_layer = 7, windows_app_package = 8, + macos_bundle = 9, }; struct FrameworkEnvironment { @@ -516,7 +518,10 @@ struct FrameworkEnvironment { fs::path get_layer_manifest_path(size_t index = 0) noexcept; fs::FolderManager& get_folder(ManifestLocation location) noexcept; - +#if defined(__APPLE__) + // Set the path of the app bundle to the appropriate test framework bundle + void setup_macos_bundle() noexcept; +#endif PlatformShimWrapper platform_shim; std::vector<fs::FolderManager> folders; diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h index 4e20eb62..98aa3758 100644 --- a/tests/framework/test_util.h +++ b/tests/framework/test_util.h @@ -169,7 +169,7 @@ struct path { path operator/(std::string const& in) const; path operator/(const char* in) const; - // accesors + // accessors path parent_path() const; bool has_parent_path() const; path filename() const; diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp index 204a1c80..0cbfc143 100644 --- a/tests/loader_regression_tests.cpp +++ b/tests/loader_regression_tests.cpp @@ -2347,7 +2347,7 @@ TEST(EnumeratePhysicalDeviceGroups, FakePNext) { // NOTE: This is a fake struct to make sure the pNext chain is properly passed down to the ICD // vkEnumeratePhysicalDeviceGroups. // The two versions must match: - // "FakePNext" test in loader_regresion_tests.cpp + // "FakePNext" test in loader_regression_tests.cpp // "test_vkEnumeratePhysicalDeviceGroups" in test_icd.cpp struct FakePnextSharedWithICD { VkStructureType sType; @@ -3643,3 +3643,49 @@ TEST(ManifestDiscovery, InvalidSymlink) { inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER); } #endif + +#if defined(__APPLE__) +// Add two drivers, one to the bundle and one to the system locations +TEST(ManifestDiscovery, AppleBundles) { + FrameworkEnvironment env{}; + env.setup_macos_bundle(); + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::macos_bundle)); + env.get_test_icd(0).physical_devices.push_back({}); + env.get_test_icd(0).physical_devices.at(0).properties.deviceID = 1337; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); + env.get_test_icd(1).physical_devices.push_back({}); + env.get_test_icd(1).physical_devices.at(0).properties.deviceID = 9999; + + InstWrapper inst{env.vulkan_functions}; + ASSERT_NO_FATAL_FAILURE(inst.CheckCreate()); + auto physical_devices = inst.GetPhysDevs(); + ASSERT_EQ(1, physical_devices.size()); + + // Verify that this is the 'right' GPU, aka the one from the bundle + VkPhysicalDeviceProperties props{}; + inst->vkGetPhysicalDeviceProperties(physical_devices[0], &props); + ASSERT_EQ(env.get_test_icd(0).physical_devices.at(0).properties.deviceID, props.deviceID); +} + +// Add two drivers, one to the bundle and one using the driver env-var +TEST(ManifestDiscovery, AppleBundlesEnvVarActive) { + FrameworkEnvironment env{}; + env.setup_macos_bundle(); + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::macos_bundle)); + env.get_test_icd(0).physical_devices.push_back({}); + env.get_test_icd(0).physical_devices.at(0).properties.deviceID = 1337; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::env_var)); + env.get_test_icd(1).physical_devices.push_back({}); + env.get_test_icd(1).physical_devices.at(0).properties.deviceID = 9999; + + InstWrapper inst{env.vulkan_functions}; + ASSERT_NO_FATAL_FAILURE(inst.CheckCreate()); + auto physical_devices = inst.GetPhysDevs(); + ASSERT_EQ(1, physical_devices.size()); + + // Verify that this is the 'right' GPU, aka the one from the env-var + VkPhysicalDeviceProperties props{}; + inst->vkGetPhysicalDeviceProperties(physical_devices[0], &props); + ASSERT_EQ(env.get_test_icd(1).physical_devices.at(0).properties.deviceID, props.deviceID); +} +#endif |