summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Giessen <charles@lunarg.com>2022-12-06 13:45:15 -0700
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2023-01-09 16:25:53 -0700
commit52ffa76190da257f6f0c99c61ebc7a69ebda356e (patch)
treef4de58e93ba275c394067f04bf16b5c4d266dc14
parent12c169db136f8f906803b429df88cb6f50698497 (diff)
downloadVulkan-Loader-52ffa76190da257f6f0c99c61ebc7a69ebda356e.tar.gz
Vulkan-Loader-52ffa76190da257f6f0c99c61ebc7a69ebda356e.tar.bz2
Vulkan-Loader-52ffa76190da257f6f0c99c61ebc7a69ebda356e.zip
Add macOS bundles support to test framework
Allow basic tests to be written which exercise the bundle discovery and loading logic in the loader. This allows testing whether drivers found in bundles disables searching for drivers on the rest of the system. This commit also inclues fixes for a half dozen non essential spelling mistakes.
-rw-r--r--loader/loader.c2
-rw-r--r--loader/trampoline.c6
-rw-r--r--tests/framework/shim/CMakeLists.txt1
-rw-r--r--tests/framework/shim/shim.h4
-rw-r--r--tests/framework/shim/shim_common.cpp13
-rw-r--r--tests/framework/shim/unix_shim.cpp36
-rw-r--r--tests/framework/test_environment.cpp23
-rw-r--r--tests/framework/test_environment.h7
-rw-r--r--tests/framework/test_util.h2
-rw-r--r--tests/loader_regression_tests.cpp48
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