diff --git a/loader/loader.c b/loader/loader.c index 2fb422cc2..d6fcb0d67 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -8214,7 +8214,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups( return res; } -VkResult get_device_driver_id(VkPhysicalDevice physicalDevice, VkDriverId *driverId) { +VkResult get_device_driver_id(const struct loader_instance *inst, VkPhysicalDevice physicalDevice, VkDriverId *driverId) { // NOLINTNEXTLINE(bugprone-invalid-enum-default-initialization) - VkDriverId is an external enum with no zero value VkPhysicalDeviceDriverProperties physical_device_driver_props = {0}; physical_device_driver_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; @@ -8223,19 +8223,16 @@ VkResult get_device_driver_id(VkPhysicalDevice physicalDevice, VkDriverId *drive props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; props2.pNext = &physical_device_driver_props; - struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; - struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; - const struct loader_instance *inst = icd_term->this_instance; - assert(inst != NULL); - // Get the function pointer to use to call into the ICD. This could be the core or KHR version + // physicalDevice was enumerated from the top of the layer chain, so a layer may have wrapped it and it must not be treated as a + // loader_physical_device_term. Query it through the layer chain instead. This could be the core or KHR version PFN_vkGetPhysicalDeviceProperties2 fpGetPhysicalDeviceProperties2 = NULL; if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { - fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2; + fpGetPhysicalDeviceProperties2 = inst->disp->layer_inst_disp.GetPhysicalDeviceProperties2; } if (fpGetPhysicalDeviceProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) { - fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2KHR; + fpGetPhysicalDeviceProperties2 = inst->disp->layer_inst_disp.GetPhysicalDeviceProperties2KHR; } if (fpGetPhysicalDeviceProperties2 == NULL) { @@ -8244,7 +8241,7 @@ VkResult get_device_driver_id(VkPhysicalDevice physicalDevice, VkDriverId *drive return VK_ERROR_UNKNOWN; } - fpGetPhysicalDeviceProperties2(phys_dev_term->phys_dev, &props2); + fpGetPhysicalDeviceProperties2(physicalDevice, &props2); *driverId = physical_device_driver_props.driverID; return VK_SUCCESS; @@ -8272,7 +8269,7 @@ VkResult loader_filter_enumerated_physical_devices(const struct loader_instance if (0 != driver_id_filter->count) { VkDriverId driver_id; - VkResult res = get_device_driver_id(in_pPhysicalDevices[i], &driver_id); + VkResult res = get_device_driver_id(inst, in_pPhysicalDevices[i], &driver_id); if ((res != VK_SUCCESS) || !check_id_matches_filter_environment_var(driver_id, driver_id_filter)) { continue; @@ -8318,7 +8315,7 @@ VkResult loader_filter_enumerated_physical_device_groups( if (0 != driver_id_filter->count) { VkDriverId driver_id; - VkResult res = get_device_driver_id(device_group->physicalDevices[j], &driver_id); + VkResult res = get_device_driver_id(inst, device_group->physicalDevices[j], &driver_id); if ((res != VK_SUCCESS) || !check_id_matches_filter_environment_var(driver_id, driver_id_filter)) { skip_group = true; diff --git a/tests/framework/layer/wrap_objects.cpp b/tests/framework/layer/wrap_objects.cpp index 0f302fc8e..5e0f659b3 100644 --- a/tests/framework/layer/wrap_objects.cpp +++ b/tests/framework/layer/wrap_objects.cpp @@ -415,6 +415,13 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physic phys_dev->inst->layer_disp.GetPhysicalDeviceProperties(vk_phys_dev, pProperties); } +VKAPI_ATTR void VKAPI_CALL wrap_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2 *pProperties) { + wrapped_phys_dev_obj *phys_dev; + auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev); + phys_dev->inst->layer_disp.GetPhysicalDeviceProperties2(vk_phys_dev, pProperties); +} + VKAPI_ATTR void VKAPI_CALL wrap_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties) { @@ -727,6 +734,7 @@ PFN_vkVoidFunction layer_intercept_instance_proc(wrapped_inst_obj *inst, const c if (!strcmp(name, "DestroyDebugUtilsMessengerEXT")) return (PFN_vkVoidFunction)wrap_vkDestroyDebugUtilsMessengerEXT; if (!strcmp(name, "GetPhysicalDeviceProperties")) return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties; + if (!strcmp(name, "GetPhysicalDeviceProperties2")) return (PFN_vkVoidFunction)wrap_vkGetPhysicalDeviceProperties2; if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties")) return (PFN_vkVoidFunction)wrap_vkGetPhysicalDeviceQueueFamilyProperties; diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp index c616505e3..0371b547c 100644 --- a/tests/loader_regression_tests.cpp +++ b/tests/loader_regression_tests.cpp @@ -1470,6 +1470,53 @@ TEST(EnumeratePhysicalDevices, DeviceFilteringByDriverId) { } } +// Layers are allowed to wrap VkPhysicalDevice handles, so the handles being filtered are not necessarily the loader's own. +TEST(EnumeratePhysicalDevices, DeviceFilteringByDriverIdWithWrappingLayer) { + FrameworkEnvironment env{}; + auto& driver = env.add_icd(TEST_ICD_PATH_VERSION_2, {}, ManifestICD{}.set_api_version(VK_API_VERSION_1_1)) + .set_min_icd_interface_version(5) + .set_icd_api_version(VK_API_VERSION_1_1) + .add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); + + auto& physical_device = driver.add_and_get_physical_device("physical_device_0"); + physical_device.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); + physical_device.driver_properties.driverID = VkDriverId(100); + + const char* wrap_objects_name = "WrapObjectsLayer"; + env.add_explicit_layer( + {}, ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS))); + + InstWrapper inst{env.vulkan_functions}; + inst.create_info.set_api_version(VK_API_VERSION_1_1); + inst.create_info.add_layer(wrap_objects_name); + inst.CheckCreate(); + + // driver id matches the filter + { + env.env_var_vk_loader_driver_id_filter.set_new_value("100"); + + uint32_t returned_physical_count = 1; + VkPhysicalDevice physical_device_handle = VK_NULL_HANDLE; + ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, &physical_device_handle)); + ASSERT_EQ(1U, returned_physical_count); + + env.env_var_vk_loader_driver_id_filter.remove_value(); + } + + // driver id does not match the filter + { + env.env_var_vk_loader_driver_id_filter.set_new_value("50"); + + uint32_t returned_physical_count = 1; + VkPhysicalDevice physical_device_handle = VK_NULL_HANDLE; + ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, &physical_device_handle)); + ASSERT_EQ(0U, returned_physical_count); + + env.env_var_vk_loader_driver_id_filter.remove_value(); + } +} + TEST(CreateDevice, ExtensionNotPresent) { FrameworkEnvironment env{}; env.add_icd(TEST_ICD_PATH_VERSION_2).add_physical_device("physical_device_0");