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-05-25 19:47:55 +0300
committerCharles Giessen <charles@lunarg.com>2022-05-26 00:49:32 +0300
commit08e2cb6c4f5d28ae811608a84550a723f5255c8d (patch)
treeae4d29ea19e4a50ac271c82820ae23302667470c
parentad05e878ee8309cfaac62f869f9d4f6431471321 (diff)
Fix a NULL inst crashing during loader_icd_scan
When checking for the portability driver field of driver manifests, the loader did not check if inst was NULL first. Since this function is called in pre-instance functions, this crashes the loader.
-rw-r--r--loader/loader.c2
-rw-r--r--tests/loader_regression_tests.cpp65
2 files changed, 66 insertions, 1 deletions
diff --git a/loader/loader.c b/loader/loader.c
index 4447fb52d..8469550d3 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -3556,7 +3556,7 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
// Skip over ICD's which contain a true "is_portability_driver" value whenever the application doesn't enable
// portability enumeration.
item = cJSON_GetObjectItem(itemICD, "is_portability_driver");
- if (item != NULL && item->type == cJSON_True && !inst->portability_enumeration_enabled) {
+ if (item != NULL && item->type == cJSON_True && inst && !inst->portability_enumeration_enabled) {
if (skipped_portability_drivers) *skipped_portability_drivers = true;
cJSON_Delete(inst, json);
json = NULL;
diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp
index 5a4b4e682..5ed718425 100644
--- a/tests/loader_regression_tests.cpp
+++ b/tests/loader_regression_tests.cpp
@@ -3254,3 +3254,68 @@ TEST(PortabilityICDConfiguration, PortabilityAndRegularICD) {
dev_info_0.CheckCreate(phys_dev);
}
}
+
+TEST(PortabilityICDConfiguration, PortabilityAndRegularICDPreInstanceFunctions) {
+ FrameworkEnvironment env{};
+ env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)));
+ env.add_icd(
+ TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_is_portability_driver(true)));
+
+ Extension first_ext{"VK_EXT_validation_features"}; // known instance extensions
+ Extension second_ext{"VK_EXT_headless_surface"};
+ env.get_test_icd().add_instance_extensions({first_ext, second_ext});
+
+ auto& driver0 = env.get_test_icd(0);
+ auto& driver1 = env.get_test_icd(1);
+
+ driver0.physical_devices.emplace_back("physical_device_0");
+ driver0.max_icd_interface_version = 1;
+
+ driver1.physical_devices.emplace_back("portability_physical_device_1");
+ driver1.max_icd_interface_version = 1;
+ {
+ // check that enumerating instance extensions work with a portability driver present
+ uint32_t extension_count = 0;
+ std::array<VkExtensionProperties, 5> extensions;
+ ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+ ASSERT_EQ(extension_count, 5U); // return debug report & debug utils + our two extensions
+
+ ASSERT_EQ(VK_SUCCESS,
+ env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()));
+ ASSERT_EQ(extension_count, 5U);
+ // loader always adds the debug report & debug utils extensions
+ ASSERT_TRUE(first_ext.extensionName == extensions[0].extensionName);
+ ASSERT_TRUE(second_ext.extensionName == extensions[1].extensionName);
+ ASSERT_TRUE(string_eq("VK_EXT_debug_report", extensions[2].extensionName));
+ ASSERT_TRUE(string_eq("VK_EXT_debug_utils", extensions[3].extensionName));
+ ASSERT_TRUE(string_eq("VK_KHR_portability_enumeration", extensions[4].extensionName));
+ }
+
+ 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)),
+ "test_layer.json");
+
+ InstWrapper inst{env.vulkan_functions};
+ inst.create_info.add_layer(layer_name);
+ inst.CheckCreate();
+
+ VkPhysicalDevice phys_dev = inst.GetPhysDev();
+ { // LayersMatch
+
+ uint32_t layer_count = 0;
+ ASSERT_EQ(env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &layer_count, nullptr), VK_SUCCESS);
+ ASSERT_EQ(layer_count, 1U);
+ VkLayerProperties layer_props;
+ ASSERT_EQ(env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &layer_count, &layer_props), VK_SUCCESS);
+ ASSERT_EQ(layer_count, 1U);
+ ASSERT_TRUE(string_eq(layer_props.layerName, layer_name));
+ }
+ { // Property count less than available
+ VkLayerProperties layer_props;
+ uint32_t layer_count = 0;
+ ASSERT_EQ(VK_INCOMPLETE, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &layer_count, &layer_props));
+ ASSERT_EQ(layer_count, 0U);
+ }
+}