Dont pass portability bit to ICDs that dont expect it
authorCharles Giessen <charles@lunarg.com>
Thu, 25 Aug 2022 18:16:54 +0000 (12:16 -0600)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Wed, 31 Aug 2022 17:49:56 +0000 (11:49 -0600)
There was a small issue with the initial version of the portability
enumeration extension where the portability enumeration flag bit would
be passed down to ICDs which did not expect flags to contain anything
other than zero.

While an argument could be made for those drivers to ignore flags they
do not recognize, just like extensions and other 'unknown' things, it
is best to play nice as this is the first instance creation flag bit
added.

loader/loader.c
tests/framework/icd/test_icd.cpp
tests/framework/icd/test_icd.h
tests/loader_regression_tests.cpp

index 406f6562376fc039e403320019cc6257ed73df5d..346582589563a9ebb18ff60aa20c658f497a7634 100644 (file)
@@ -5322,6 +5322,21 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI
             }
         }
 
+        // Remove the portability enumeration flag bit if the ICD doesn't support the extension
+        if ((pCreateInfo->flags & VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR) == 1) {
+            bool supports_portability_enumeration = false;
+            for (uint32_t j = 0; j < icd_create_info.enabledExtensionCount; j++) {
+                if (strcmp(filtered_extension_names[j], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) {
+                    supports_portability_enumeration = true;
+                    break;
+                }
+            }
+            // If the icd supports the extension, use the flags as given, otherwise remove the portability bit
+            icd_create_info.flags = supports_portability_enumeration
+                                        ? pCreateInfo->flags
+                                        : pCreateInfo->flags & (~VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR);
+        }
+
         // Create an instance, substituting the version to 1.0 if necessary
         VkApplicationInfo icd_app_info;
         uint32_t icd_version_nopatch =
index 5f0bc44bca22e9633d5389fb9091184bc73f8805..c618d68d1e153d215951df07868007c85005c554 100644 (file)
@@ -194,6 +194,8 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo*
     // VK_SUCCESS
     *pInstance = icd.instance_handle.handle;
 
+    icd.passed_in_instance_create_flags = pCreateInfo->flags;
+
     return VK_SUCCESS;
 }
 
@@ -1425,4 +1427,4 @@ FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDe
 #endif  // defined(WIN32)
 #endif  // TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
 
-}  // extern "C"
\ No newline at end of file
+}  // extern "C"
index 79bd525f544df21aa880608820ee9b90d3813aae..14bf4554d261bde8e642fc840a315d7f24ac3081 100644 (file)
@@ -94,6 +94,8 @@ struct TestICD {
     std::vector<VkPhysicalDeviceToolPropertiesEXT> tooling_properties;
     std::vector<DispatchableHandle<VkCommandBuffer>> allocated_command_buffers;
 
+    VkInstanceCreateFlags passed_in_instance_create_flags{};
+
     PhysicalDevice& GetPhysDevice(VkPhysicalDevice physicalDevice) {
         for (auto& phys_dev : physical_devices) {
             if (phys_dev.vk_physical_device.handle == physicalDevice) return phys_dev;
@@ -118,4 +120,4 @@ using GetTestICDFunc = TestICD* (*)();
 #define GET_TEST_ICD_FUNC_STR "get_test_icd_func"
 
 using GetNewTestICDFunc = TestICD* (*)();
-#define RESET_ICD_FUNC_STR "reset_icd_func"
\ No newline at end of file
+#define RESET_ICD_FUNC_STR "reset_icd_func"
index 0b7389ecd5a982759ba2c2ed629acb7a0c54ef16..97a2a74052639fb372c9c3867edf76b638ba65a5 100644 (file)
@@ -3422,6 +3422,36 @@ TEST(PortabilityICDConfiguration, PortabilityAndRegularICD) {
     }
 }
 
+// Check that the portability enumeration flag bit doesn't get passed down
+TEST(PortabilityICDConfiguration, PortabilityAndRegularICDCheckFlagsPassedIntoICD) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2)));
+    env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2).set_is_portability_driver(true)));
+
+    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.add_instance_extension("VK_KHR_portability_enumeration");
+    driver1.max_icd_interface_version = 1;
+
+    InstWrapper inst{env.vulkan_functions};
+    inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+    inst.create_info.add_extension("VK_KHR_portability_enumeration");
+    inst.create_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR | 4;
+
+    FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+    inst.CheckCreate();
+    ASSERT_FALSE(env.debug_log.find(portability_driver_warning));
+
+    ASSERT_EQ(static_cast<VkInstanceCreateFlags>(4), driver0.passed_in_instance_create_flags);
+    ASSERT_EQ(VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR | static_cast<VkInstanceCreateFlags>(4),
+              driver1.passed_in_instance_create_flags);
+}
+
 TEST(PortabilityICDConfiguration, PortabilityAndRegularICDPreInstanceFunctions) {
     FrameworkEnvironment env{};
     env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)));