Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/Vulkan-Loader.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Giessen <charles@lunarg.com>2022-06-20 23:38:56 +0300
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2022-06-22 19:28:18 +0300
commit865626abbafda93a236398ac35627407d62dbe6f (patch)
treebd901e10f9f367f8743bc3cb58ed7533c766517f
parent8d3d6d4e1635aabfe0cd66b628ba30278179b5d9 (diff)
Add 32 & 64 bit field to json manifests
Allows drivers and layers to specify if they are 32 bit or 64 bit in the manifest file. This makes the loader able to prune manifests without loading the library and finding that it failed to load.
-rw-r--r--docs/LoaderDriverInterface.md14
-rw-r--r--docs/LoaderLayerInterface.md18
-rw-r--r--loader/loader.c31
-rw-r--r--tests/framework/test_util.cpp13
-rw-r--r--tests/framework/test_util.h4
-rw-r--r--tests/loader_regression_tests.cpp36
6 files changed, 110 insertions, 6 deletions
diff --git a/docs/LoaderDriverInterface.md b/docs/LoaderDriverInterface.md
index 12c964a58..1021dd41d 100644
--- a/docs/LoaderDriverInterface.md
+++ b/docs/LoaderDriverInterface.md
@@ -516,6 +516,7 @@ Here is an example driver JSON Manifest file:
"ICD": {
"library_path": "path to driver library",
"api_version": "1.2.205",
+ "library_arch" : "64",
"is_portability_driver": false
}
}
@@ -551,6 +552,14 @@ Here is an example driver JSON Manifest file:
Windows, ".so" on Linux and ".dylib" on macOS).</td>
</tr>
<tr>
+ <td>"library_arch"</td>
+ <td>Optional field which specifies the architecture of the binary associated
+ with "library_path". <br />
+ Allows the loader to quickly determine if the architecture of the driver
+ matches that of the running application. <br />
+ The only valid values are "32" and "64".</td>
+ </tr>
+ <tr>
<td>"api_version" </td>
<td>The major.minor.patch version number of the maximum Vulkan API supported
by the driver.
@@ -574,7 +583,7 @@ Here is an example driver JSON Manifest file:
versions of text manifest file format versions, it must have separate JSON files
for each (all of which may point to the same shared library).
-#### Driver Manifest File Versions
+### Driver Manifest File Versions
The current highest supported Layer Manifest file format supported is 1.0.1.
Information about each version is detailed in the following sub-sections:
@@ -596,6 +605,9 @@ they contain VkPhysicalDevices which support the VK_KHR_portability_subset
extension. This is an optional field. Omitting the field has the same effect as
setting the field to `false`.
+Added the "library\_arch" field to the driver manifest to allow the loader to
+quickly determine if the driver matches the architecture of the current running
+application. This field is optional.
## Driver Vulkan Entry Point Discovery
diff --git a/docs/LoaderLayerInterface.md b/docs/LoaderLayerInterface.md
index ba9d6afde..36631684c 100644
--- a/docs/LoaderLayerInterface.md
+++ b/docs/LoaderLayerInterface.md
@@ -1437,11 +1437,12 @@ Here is an example layer JSON Manifest file with a single layer:
```json
{
- "file_format_version" : "1.0.0",
+ "file_format_version" : "1.2.1",
"layer": {
"name": "VK_LAYER_LUNARG_overlay",
"type": "INSTANCE",
"library_path": "vkOverlayLayer.dll",
+ "library_arch" : "64",
"api_version" : "1.0.5",
"implementation_version" : "2",
"description" : "LunarG HUD layer",
@@ -1708,6 +1709,15 @@ Here's an example of a meta-layer manifest file:
<td>"layer"/"layers"</td>
<td><small>N/A</small></td>
</tr>
+ <td>"library_arch"</td>
+ <td>Optional field which specifies the architecture of the binary associated
+ with "library_path". <br />
+ Allows the loader to quickly determine if the architecture of the layer
+ matches that of the running application. <br />
+ The only valid values are "32" and "64".</td>
+ <td><small>N/A</small></td>
+ </tr>
+ <tr>
<tr>
<td>"name"</td>
<td>The string used to uniquely identify this layer to applications.</td>
@@ -1764,6 +1774,12 @@ Here's an example of a meta-layer manifest file:
The current highest supported Layer Manifest file format supported is 1.2.0.
Information about each version is detailed in the following sub-sections:
+### Layer Manifest File Version 1.2.1
+
+Added the "library\_arch" field to the layer manifest to allow the loader to
+quickly determine if the layer matches the architecture of the current running
+application.
+
#### Layer Manifest File Version 1.2.0
The ability to define the layer settings as defined by the
diff --git a/loader/loader.c b/loader/loader.c
index 6e565f5aa..fd59f199c 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -2256,6 +2256,7 @@ static VkResult loader_read_layer_json(const struct loader_instance *inst, struc
// instance_extensions
// device_extensions
// enable_environment (implicit layers only)
+// library_arch
#define GET_JSON_OBJECT(node, var) \
{ var = cJSON_GetObjectItem(node, #var); }
#define GET_JSON_ITEM(inst, node, var) \
@@ -2282,6 +2283,7 @@ static VkResult loader_read_layer_json(const struct loader_instance *inst, struc
char *vkNegotiateLoaderLayerInterfaceVersion = NULL;
char *spec_version = NULL;
char **entry_array = NULL;
+ char *library_arch = NULL;
cJSON *app_keys = NULL;
// Layer interface functions
@@ -2511,6 +2513,16 @@ static VkResult loader_read_layer_json(const struct loader_instance *inst, struc
}
}
+ GET_JSON_ITEM(inst, layer_node, library_arch)
+ if (library_arch != NULL) {
+ if ((strncmp(library_arch, "32", 2) == 0 && sizeof(void *) != 4) ||
+ (strncmp(library_arch, "64", 2) == 0 && sizeof(void *) != 8)) {
+ loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+ "Layer library architecture doesn't match the current running architecture, skipping this layer");
+ goto out;
+ }
+ }
+
result = VK_SUCCESS;
out:
@@ -3538,6 +3550,25 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
continue;
}
+ item = cJSON_GetObjectItem(itemICD, "library_arch");
+ if (item != NULL) {
+ temp = cJSON_Print(item);
+ if (NULL != temp) {
+ // cJSON includes the quotes by default, so we need to look for those here
+ if ((strncmp(temp, "\"32\"", 4) == 0 && sizeof(void *) != 4) ||
+ (strncmp(temp, "\"64\"", 4) == 0 && sizeof(void *) != 8)) {
+ loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+ "loader_icd_scan: Driver library architecture doesn't match the current running "
+ "architecture, skipping this driver");
+ loader_instance_heap_free(inst, temp);
+ cJSON_Delete(json);
+ json = NULL;
+ continue;
+ }
+ }
+ loader_instance_heap_free(inst, temp);
+ }
+
VkResult icd_add_res = VK_SUCCESS;
enum loader_layer_library_status lib_status;
icd_add_res = loader_scanned_icd_add(inst, icd_tramp_list, fullpath, vers, &lib_status);
diff --git a/tests/framework/test_util.cpp b/tests/framework/test_util.cpp
index 3acc64050..6b796e7ce 100644
--- a/tests/framework/test_util.cpp
+++ b/tests/framework/test_util.cpp
@@ -137,7 +137,12 @@ std::string ManifestICD::get_manifest_str() const {
out += " \"ICD\": {\n";
out += " \"library_path\": \"" + fs::fixup_backslashes_in_path(lib_path) + "\",\n";
out += " \"api_version\": \"" + version_to_string(api_version) + "\",\n";
- out += " \"is_portability_driver\": " + to_text(is_portability_driver) + "\n";
+ out += " \"is_portability_driver\": " + to_text(is_portability_driver);
+ if (!library_arch.empty()) {
+ out += ",\n \"library_arch\": \"" + library_arch + "\"\n";
+ } else {
+ out += "\n";
+ }
out += " }\n";
out += "}\n";
return out;
@@ -176,7 +181,9 @@ std::string ManifestLayer::LayerDescription::get_manifest_str() const {
print_vector_of_strings(out, "override_paths", override_paths);
print_vector_of_strings(out, "app_keys", app_keys);
print_list_of_t(out, "pre_instance_functions", pre_instance_functions);
-
+ if (!library_arch.empty()) {
+ out += ",\n\t\t\"library_arch\": \"" + library_arch + "\"";
+ }
out += "\n\t}";
return out;
@@ -664,4 +671,4 @@ VkDeviceCreateInfo* DeviceCreateInfo::get() noexcept {
dev.queueCreateInfoCount = static_cast<uint32_t>(device_queue_infos.size());
dev.pQueueCreateInfos = device_queue_infos.data();
return &dev;
-} \ No newline at end of file
+}
diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h
index 2ab87645f..376602414 100644
--- a/tests/framework/test_util.h
+++ b/tests/framework/test_util.h
@@ -543,6 +543,7 @@ struct ManifestICD {
BUILDER_VALUE(ManifestICD, uint32_t, api_version, 0)
BUILDER_VALUE(ManifestICD, std::string, lib_path, {})
BUILDER_VALUE(ManifestICD, bool, is_portability_driver, false)
+ BUILDER_VALUE(ManifestICD, std::string, library_arch, "")
std::string get_manifest_str() const;
};
@@ -589,6 +590,7 @@ struct ManifestLayer {
BUILDER_VECTOR(LayerDescription, std::string, override_paths, override_path)
BUILDER_VECTOR(LayerDescription, FunctionOverride, pre_instance_functions, pre_instance_function)
BUILDER_VECTOR(LayerDescription, std::string, app_keys, app_key)
+ BUILDER_VALUE(LayerDescription, std::string, library_arch, "")
std::string get_manifest_str() const;
VkLayerProperties get_layer_properties() const;
@@ -963,4 +965,4 @@ static inline std::string test_platform_executable_path() {
buffer[ret] = '\0';
return buffer;
}
-#endif \ No newline at end of file
+#endif
diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp
index 141c1aa79..bd8fdeebf 100644
--- a/tests/loader_regression_tests.cpp
+++ b/tests/loader_regression_tests.cpp
@@ -1303,6 +1303,42 @@ TEST(TryLoadWrongBinaries, BadExplicitAndImplicit) {
ASSERT_TRUE(log.find(std::string("Requested layer ") + std::string(layer_name_1) + std::string(" failed to load.")));
}
+TEST(TryLoadWrongBinaries, WrongArchDriver) {
+ FrameworkEnvironment env{};
+ // Intentionally set the wrong arch
+ env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}.icd_manifest.set_library_arch(sizeof(void*) == 4 ? "64" : "32"));
+
+ env.get_test_icd().physical_devices.emplace_back("physical_device_0");
+
+ DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
+ InstWrapper inst{env.vulkan_functions};
+ FillDebugUtilsCreateDetails(inst.create_info, log);
+ inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+ ASSERT_TRUE(log.find(
+ "loader_icd_scan: Driver library architecture doesn't match the current running architecture, skipping this driver"));
+}
+
+TEST(TryLoadWrongBinaries, WrongArchLayer) {
+ FrameworkEnvironment env{};
+ env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2});
+ env.get_test_icd().physical_devices.emplace_back("physical_device_0");
+
+ const char* layer_name = "TestLayer";
+ env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+ .set_name(layer_name)
+ .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
+ // Intentionally set the wrong arch
+ .set_library_arch(sizeof(void*) == 4 ? "64" : "32")),
+ "test_layer.json");
+
+ DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT};
+ InstWrapper inst{env.vulkan_functions};
+ FillDebugUtilsCreateDetails(inst.create_info, log);
+ inst.create_info.add_layer(layer_name);
+ inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
+ ASSERT_TRUE(log.find("Layer library architecture doesn't match the current running architecture, skipping this layer"));
+}
+
TEST(EnumeratePhysicalDeviceGroups, OneCall) {
FrameworkEnvironment env{};
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));