| /* |
| * Copyright (c) 2021 The Khronos Group Inc. |
| * Copyright (c) 2021 Valve Corporation |
| * Copyright (c) 2021 LunarG, Inc. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and/or associated documentation files (the "Materials"), to |
| * deal in the Materials without restriction, including without limitation the |
| * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| * sell copies of the Materials, and to permit persons to whom the Materials are |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice(s) and this permission notice shall be included in |
| * all copies or substantial portions of the Materials. |
| * |
| * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE |
| * USE OR OTHER DEALINGS IN THE MATERIALS. |
| * |
| * Author: Charles Giessen <charles@lunarg.com> |
| */ |
| |
| #include "test_environment.h" |
| |
| // Test case origin |
| // LX = lunar exchange |
| // LVLGH = loader and validation github |
| // LVLGL = loader and validation gitlab |
| // VL = Vulkan Loader github |
| // VVL = Vulkan Validation Layers github |
| |
| class RegressionTests : public ::testing::Test { |
| protected: |
| virtual void SetUp() { |
| env = std::unique_ptr<SingleICDShim>(new SingleICDShim(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_MAKE_VERSION(1, 0, 0)))); |
| } |
| |
| virtual void TearDown() { env.reset(); } |
| std::unique_ptr<SingleICDShim> env; |
| }; |
| |
| // Subtyping for organization |
| class CreateInstance : public RegressionTests {}; |
| class EnumerateInstanceVersion : public RegressionTests {}; |
| class EnumerateInstanceLayerProperties : public RegressionTests {}; |
| class EnumerateInstanceExtensionProperties : public RegressionTests {}; |
| class EnumerateDeviceLayerProperties : public RegressionTests {}; |
| class EnumerateDeviceExtensionProperties : public RegressionTests {}; |
| class EnumeratePhysicalDevices : public RegressionTests {}; |
| class CreateDevice : public RegressionTests {}; |
| class EnumeratePhysicalDeviceGroups : public RegressionTests {}; |
| class WrapObjects : public RegressionTests {}; |
| |
| TEST_F(CreateInstance, BasicRun) { |
| auto& driver = env->get_test_icd(); |
| driver.SetMinICDInterfaceVersion(5); |
| |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| } |
| |
| // LX435 |
| TEST_F(CreateInstance, ConstInstanceInfo) { |
| VkInstance inst = VK_NULL_HANDLE; |
| VkInstanceCreateInfo const info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr}; |
| ASSERT_EQ(env->vulkan_functions.vkCreateInstance(&info, VK_NULL_HANDLE, &inst), VK_SUCCESS); |
| // Must clean up |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| } |
| |
| // VUID-vkDestroyInstance-instance-parameter, VUID-vkDestroyInstance-pAllocator-parameter |
| TEST_F(CreateInstance, DestroyInstanceNullHandle) { env->vulkan_functions.vkDestroyInstance(VK_NULL_HANDLE, nullptr); } |
| |
| // VUID-vkDestroyDevice-device-parameter, VUID-vkDestroyDevice-pAllocator-parameter |
| TEST_F(CreateInstance, DestroyDeviceNullHandle) { env->vulkan_functions.vkDestroyDevice(VK_NULL_HANDLE, nullptr); } |
| |
| // VUID-vkCreateInstance-ppEnabledExtensionNames-01388 |
| TEST_F(CreateInstance, ExtensionNotPresent) { |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.add_extension("VK_EXT_validation_features"); // test icd won't report this as supported |
| inst.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| } |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.add_extension("Non_existant_extension"); // unknown instance extension |
| inst.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| } |
| } |
| |
| TEST_F(CreateInstance, LayerNotPresent) { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.add_layer("VK_NON_EXISTANT_LAYER"); |
| inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT); |
| } |
| |
| TEST_F(CreateInstance, LayerPresent) { |
| const char* layer_name = "TestLayer"; |
| ManifestLayer::LayerDescription description{}; |
| description.name = layer_name; |
| description.lib_path = TEST_LAYER_PATH_EXPORT_VERSION_1; |
| |
| ManifestLayer layer; |
| layer.layers.push_back(description); |
| env->AddExplicitLayer(layer, "test_layer.json"); |
| |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.add_layer(layer_name); |
| inst.CheckCreate(); |
| } |
| |
| TEST_F(EnumerateInstanceLayerProperties, UsageChecks) { |
| const char* layer_name_1 = "TestLayer1"; |
| const char* layer_name_2 = "TestLayer1"; |
| |
| ManifestLayer::LayerDescription description1{}; |
| description1.name = layer_name_1; |
| description1.lib_path = TEST_LAYER_PATH_EXPORT_VERSION_2; |
| |
| ManifestLayer layer1; |
| layer1.layers.push_back(description1); |
| env->AddExplicitLayer(layer1, "test_layer_1.json"); |
| |
| ManifestLayer::LayerDescription description2{}; |
| description2.name = layer_name_1; |
| description2.lib_path = TEST_LAYER_PATH_EXPORT_VERSION_2; |
| |
| ManifestLayer layer2; |
| layer2.layers.push_back(description2); |
| env->AddExplicitLayer(layer2, "test_layer_2.json"); |
| |
| { // OnePass |
| VkLayerProperties layer_props[2] = {}; |
| uint32_t layer_count = 2; |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props)); |
| ASSERT_EQ(layer_count, 2); |
| ASSERT_TRUE(string_eq(layer_name_1, layer_props[0].layerName)); |
| ASSERT_TRUE(string_eq(layer_name_2, layer_props[1].layerName)); |
| } |
| { // OnePass |
| uint32_t layer_count = 0; |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr)); |
| ASSERT_EQ(layer_count, 2); |
| |
| VkLayerProperties layer_props[2] = {}; |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props)); |
| ASSERT_EQ(layer_count, 2); |
| ASSERT_TRUE(string_eq(layer_name_1, layer_props[0].layerName)); |
| ASSERT_TRUE(string_eq(layer_name_2, layer_props[1].layerName)); |
| } |
| { // PropertyCountLessThanAvailable |
| VkLayerProperties layer_props{}; |
| uint32_t layer_count = 1; |
| ASSERT_EQ(VK_INCOMPLETE, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, &layer_props)); |
| ASSERT_TRUE(string_eq(layer_name_1, layer_props.layerName)); |
| } |
| } |
| |
| TEST_F(EnumerateInstanceExtensionProperties, UsageChecks) { |
| Extension first_ext{"VK_EXT_validation_features"}; // known instance extensions |
| Extension second_ext{"VK_EXT_headless_surface"}; |
| env->reset_icd().AddInstanceExtensions({first_ext, second_ext}); |
| |
| { // One Pass |
| uint32_t extension_count = 4; |
| std::array<VkExtensionProperties, 4> extensions; |
| ASSERT_EQ(VK_SUCCESS, |
| env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data())); |
| ASSERT_EQ(extension_count, 4); // return debug report & debug utils + our two extensions |
| |
| // 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)); |
| } |
| { // Two Pass |
| uint32_t extension_count = 0; |
| std::array<VkExtensionProperties, 4> extensions; |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr)); |
| ASSERT_EQ(extension_count, 4); // 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, 4); |
| // 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)); |
| } |
| } |
| |
| TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable) { |
| uint32_t extension_count = 0; |
| std::array<VkExtensionProperties, 2> extensions; |
| { // use nullptr for null string |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr)); |
| ASSERT_EQ(extension_count, 2); // return debug report & debug utils |
| extension_count = 1; // artificially remove one extension |
| |
| ASSERT_EQ(VK_INCOMPLETE, |
| env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data())); |
| ASSERT_EQ(extension_count, 1); |
| // loader always adds the debug report & debug utils extensions |
| ASSERT_TRUE(string_eq(extensions[0].extensionName, "VK_EXT_debug_report")); |
| } |
| { // use "" for null string |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties("", &extension_count, nullptr)); |
| ASSERT_EQ(extension_count, 2); // return debug report & debug utils |
| extension_count = 1; // artificially remove one extension |
| |
| ASSERT_EQ(VK_INCOMPLETE, |
| env->vulkan_functions.vkEnumerateInstanceExtensionProperties("", &extension_count, extensions.data())); |
| ASSERT_EQ(extension_count, 1); |
| // loader always adds the debug report & debug utils extensions |
| ASSERT_TRUE(string_eq(extensions[0].extensionName, "VK_EXT_debug_report")); |
| } |
| } |
| |
| TEST_F(EnumerateInstanceExtensionProperties, FilterUnkownInstanceExtensions) { |
| Extension first_ext{"FirstTestExtension"}; // unknown instance extensions |
| Extension second_ext{"SecondTestExtension"}; |
| env->reset_icd().AddInstanceExtensions({first_ext, second_ext}); |
| { |
| uint32_t extension_count = 0; |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties("", &extension_count, nullptr)); |
| ASSERT_EQ(extension_count, 2); // return debug report & debug utils |
| |
| std::array<VkExtensionProperties, 2> extensions; |
| ASSERT_EQ(VK_SUCCESS, |
| env->vulkan_functions.vkEnumerateInstanceExtensionProperties("", &extension_count, extensions.data())); |
| ASSERT_EQ(extension_count, 2); |
| // loader always adds the debug report & debug utils extensions |
| ASSERT_TRUE(string_eq(extensions[0].extensionName, "VK_EXT_debug_report")); |
| ASSERT_TRUE(string_eq(extensions[1].extensionName, "VK_EXT_debug_utils")); |
| } |
| { // Disable unknown instance extension filtering |
| set_env_var("VK_LOADER_DISABLE_INST_EXT_FILTER", "1"); |
| |
| uint32_t extension_count = 0; |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties("", &extension_count, nullptr)); |
| ASSERT_EQ(extension_count, 4); |
| |
| std::array<VkExtensionProperties, 4> extensions; |
| ASSERT_EQ(VK_SUCCESS, |
| env->vulkan_functions.vkEnumerateInstanceExtensionProperties("", &extension_count, extensions.data())); |
| ASSERT_EQ(extension_count, 4); |
| |
| ASSERT_EQ(extensions[0], first_ext.get()); |
| ASSERT_EQ(extensions[1], second_ext.get()); |
| // Loader always adds these two extensions |
| ASSERT_TRUE(string_eq(extensions[2].extensionName, "VK_EXT_debug_report")); |
| ASSERT_TRUE(string_eq(extensions[3].extensionName, "VK_EXT_debug_utils")); |
| } |
| } |
| |
| TEST_F(EnumerateDeviceLayerProperties, LayersMatch) { |
| auto& driver = env->get_test_icd(); |
| driver.physical_devices.emplace_back("physical_device_0"); |
| |
| const char* layer_name = "TestLayer"; |
| ManifestLayer::LayerDescription description{}; |
| description.name = layer_name; |
| description.lib_path = TEST_LAYER_PATH_EXPORT_VERSION_2; |
| |
| ManifestLayer layer; |
| layer.layers.push_back(description); |
| env->AddExplicitLayer(layer, "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, 1); |
| VkLayerProperties layer_props; |
| ASSERT_EQ(env->vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &layer_count, &layer_props), VK_SUCCESS); |
| ASSERT_EQ(layer_count, 1); |
| 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, 0); |
| } |
| } |
| |
| TEST_F(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) { |
| auto& driver = env->get_test_icd(); |
| driver.physical_devices.emplace_back("physical_device_0"); |
| |
| std::array<Extension, 2> device_extensions = {Extension{"MyExtension0", 4}, Extension{"MyExtension1", 7}}; |
| for (auto& ext : device_extensions) { |
| driver.physical_devices.front().extensions.push_back(ext); |
| } |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device)); |
| |
| uint32_t extension_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &extension_count, nullptr)); |
| ASSERT_EQ(extension_count, device_extensions.size()); |
| |
| std::array<VkExtensionProperties, 2> enumerated_device_exts; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &extension_count, |
| enumerated_device_exts.data())); |
| ASSERT_EQ(extension_count, device_extensions.size()); |
| ASSERT_TRUE(device_extensions[0].extensionName == enumerated_device_exts[0].extensionName); |
| ASSERT_TRUE(device_extensions[0].specVersion == enumerated_device_exts[0].specVersion); |
| } |
| |
| TEST_F(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable) { |
| auto& driver = env->get_test_icd(); |
| driver.physical_devices.emplace_back("physical_device_0"); |
| |
| std::array<Extension, 2> device_extensions = {Extension{"MyExtension0", 4}, Extension{"MyExtension1", 7}}; |
| for (auto& ext : device_extensions) { |
| driver.physical_devices.front().extensions.push_back(ext); |
| } |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device)); |
| |
| uint32_t extension_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumerateDeviceExtensionProperties(physical_device, "", &extension_count, nullptr)); |
| ASSERT_EQ(extension_count, device_extensions.size()); |
| extension_count -= 1; |
| |
| std::array<VkExtensionProperties, 2> enumerated_device_exts; |
| ASSERT_EQ(VK_INCOMPLETE, |
| inst->vkEnumerateDeviceExtensionProperties(physical_device, "", &extension_count, enumerated_device_exts.data())); |
| ASSERT_EQ(extension_count, device_extensions.size() - 1); |
| ASSERT_TRUE(device_extensions[0].extensionName == enumerated_device_exts[0].extensionName); |
| ASSERT_TRUE(device_extensions[0].specVersion == enumerated_device_exts[0].specVersion); |
| } |
| |
| TEST_F(EnumeratePhysicalDevices, OneCall) { |
| auto& driver = env->get_test_icd().SetMinICDInterfaceVersion(5); |
| |
| driver.physical_devices.emplace_back("physical_device_0"); |
| driver.physical_devices.emplace_back("physical_device_1"); |
| driver.physical_devices.emplace_back("physical_device_2"); |
| driver.physical_devices.emplace_back("physical_device_3"); |
| |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| |
| uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size()); |
| uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size()); |
| std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count); |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_physical_count, physical_device_handles.data())); |
| ASSERT_EQ(physical_count, returned_physical_count); |
| } |
| |
| TEST_F(EnumeratePhysicalDevices, TwoCall) { |
| auto& driver = env->get_test_icd().SetMinICDInterfaceVersion(5); |
| |
| const uint32_t real_device_count = 2; |
| for (size_t i = 0; i < real_device_count; i++) { |
| driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i)); |
| } |
| |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| |
| uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size()); |
| uint32_t returned_physical_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr)); |
| ASSERT_EQ(physical_count, returned_physical_count); |
| |
| std::array<VkPhysicalDevice, real_device_count> physical_device_handles; |
| ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, |
| physical_device_handles.data())); |
| ASSERT_EQ(physical_count, returned_physical_count); |
| } |
| |
| TEST_F(EnumeratePhysicalDevices, MatchOneAndTwoCallNumbers) { |
| auto& driver = env->get_test_icd(); |
| driver.SetMinICDInterfaceVersion(5); |
| |
| const uint32_t real_device_count = 3; |
| for (size_t i = 0; i < real_device_count; i++) { |
| driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i)); |
| } |
| |
| InstWrapper inst1{env->vulkan_functions}; |
| inst1.CheckCreate(); |
| |
| uint32_t physical_count_one_call = static_cast<uint32_t>(driver.physical_devices.size()); |
| std::array<VkPhysicalDevice, real_device_count> physical_device_handles_one_call; |
| ASSERT_EQ(VK_SUCCESS, |
| inst1->vkEnumeratePhysicalDevices(inst1, &physical_count_one_call, physical_device_handles_one_call.data())); |
| ASSERT_EQ(real_device_count, physical_count_one_call); |
| |
| InstWrapper inst2{env->vulkan_functions}; |
| inst2.CheckCreate(); |
| |
| uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size()); |
| uint32_t returned_physical_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst2->vkEnumeratePhysicalDevices(inst2, &returned_physical_count, nullptr)); |
| ASSERT_EQ(physical_count, returned_physical_count); |
| |
| std::array<VkPhysicalDevice, real_device_count> physical_device_handles; |
| ASSERT_EQ(VK_SUCCESS, inst2->vkEnumeratePhysicalDevices(inst2, &returned_physical_count, physical_device_handles.data())); |
| ASSERT_EQ(real_device_count, returned_physical_count); |
| |
| ASSERT_EQ(physical_count_one_call, returned_physical_count); |
| } |
| |
| TEST_F(EnumeratePhysicalDevices, TwoCallIncomplete) { |
| auto& driver = env->get_test_icd().SetMinICDInterfaceVersion(5); |
| |
| const uint32_t real_device_count = 2; |
| for (size_t i = 0; i < real_device_count; i++) { |
| driver.physical_devices.emplace_back(std::string("physical_device_") + std::to_string(i)); |
| } |
| |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| |
| uint32_t physical_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &physical_count, nullptr)); |
| ASSERT_EQ(physical_count, driver.physical_devices.size()); |
| |
| std::array<VkPhysicalDevice, real_device_count> physical; |
| |
| // Remove one from the physical device count so we can get the VK_INCOMPLETE message |
| physical_count = 1; |
| |
| ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &physical_count, physical.data())); |
| ASSERT_EQ(physical_count, 1); |
| } |
| |
| TEST_F(CreateDevice, ExtensionNotPresent) { |
| auto& driver = env->get_test_icd(); |
| |
| MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true}; |
| |
| driver.physical_devices.emplace_back("physical_device_0"); |
| driver.physical_devices.back().queue_family_properties.push_back(family_props); |
| |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| |
| VkPhysicalDevice phys_dev = inst.GetPhysDev(); |
| |
| uint32_t familyCount = 0; |
| inst->vkGetPhysicalDeviceQueueFamilyProperties(phys_dev, &familyCount, nullptr); |
| ASSERT_EQ(familyCount, 1); |
| |
| VkQueueFamilyProperties families; |
| inst->vkGetPhysicalDeviceQueueFamilyProperties(phys_dev, &familyCount, &families); |
| ASSERT_EQ(familyCount, 1); |
| ASSERT_EQ(families, family_props.properties); |
| |
| DeviceWrapper dev{inst}; |
| dev.create_info.add_extension("NotPresent").add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f)); |
| |
| dev.CheckCreate(phys_dev, VK_ERROR_EXTENSION_NOT_PRESENT); |
| } |
| |
| // LX535 / MI-76: Device layers are deprecated. |
| // Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice. |
| // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-layers-devicelayerdeprecation |
| TEST_F(CreateDevice, LayersNotPresent) { |
| auto& driver = env->get_test_icd(); |
| |
| MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true}; |
| |
| driver.physical_devices.emplace_back("physical_device_0"); |
| driver.physical_devices.back().queue_family_properties.push_back(family_props); |
| |
| InstWrapper inst{env->vulkan_functions}; |
| inst.CheckCreate(); |
| |
| VkPhysicalDevice phys_dev = inst.GetPhysDev(); |
| |
| uint32_t familyCount = 0; |
| inst->vkGetPhysicalDeviceQueueFamilyProperties(phys_dev, &familyCount, nullptr); |
| ASSERT_EQ(familyCount, 1); |
| |
| VkQueueFamilyProperties families; |
| inst->vkGetPhysicalDeviceQueueFamilyProperties(phys_dev, &familyCount, &families); |
| ASSERT_EQ(familyCount, 1); |
| ASSERT_EQ(families, family_props.properties); |
| |
| DeviceWrapper dev{inst}; |
| DeviceCreateInfo dev_create_info; |
| dev.create_info.add_layer("NotPresent").add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f)); |
| |
| dev.CheckCreate(phys_dev); |
| } |
| |
| TEST(TryLoadWrongBinaries, WrongICD) { |
| FakeBinaryICDShim env(TestICDDetails(TEST_ICD_PATH_VERSION_2), TestICDDetails(CURRENT_PLATFORM_DUMMY_BINARY)); |
| 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(); |
| |
| #if _WIN32 || _WIN64 |
| ASSERT_TRUE(log.find("Failed to open dynamic library")); |
| #endif |
| #if defined(__linux__) || defined(__FreeBSD__) |
| #if defined(__x86_64__) |
| ASSERT_TRUE(log.find("wrong ELF class: ELFCLASS32")); |
| #else |
| ASSERT_TRUE(log.find("wrong ELF class: ELFCLASS64")); |
| #endif |
| #endif |
| |
| uint32_t driver_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, nullptr)); |
| ASSERT_EQ(driver_count, 1); |
| } |
| |
| TEST(TryLoadWrongBinaries, WrongExplicitAndImplicit) { |
| SingleICDShim env(TestICDDetails(TEST_ICD_PATH_VERSION_2)); |
| env.get_test_icd().physical_devices.emplace_back("physical_device_0"); |
| |
| const char* layer_name_0 = "DummyLayerExplicit"; |
| auto description_0 = ManifestLayer::LayerDescription{}; |
| description_0.name = layer_name_0; |
| description_0.lib_path = CURRENT_PLATFORM_DUMMY_BINARY; |
| |
| ManifestLayer layer_0; |
| layer_0.layers.push_back(description_0); |
| |
| auto layer_loc_0 = env.explicit_layer_folder.write("dummy_test_layer_0.json", layer_0); |
| env.platform_shim->add_manifest(ManifestCategory::explicit_layer, layer_loc_0); |
| |
| const char* layer_name_1 = "DummyLayerImplicit"; |
| auto description_1 = ManifestLayer::LayerDescription{}; |
| description_1.name = layer_name_1; |
| description_1.lib_path = CURRENT_PLATFORM_DUMMY_BINARY; |
| description_1.disable_environment = "DISABLE_ENV"; |
| |
| ManifestLayer layer_1; |
| layer_1.layers.push_back(description_1); |
| |
| auto layer_loc_1 = env.implicit_layer_folder.write("dummy_test_layer_1.json", layer_1); |
| env.platform_shim->add_manifest(ManifestCategory::implicit_layer, layer_loc_1); |
| |
| uint32_t layer_count = 0; |
| ASSERT_EQ(env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr), VK_SUCCESS); |
| ASSERT_EQ(layer_count, 2); |
| |
| std::array<VkLayerProperties, 2> layer_props; |
| ASSERT_EQ(env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()), VK_SUCCESS); |
| ASSERT_EQ(layer_count, 2); |
| |
| InstWrapper inst{env.vulkan_functions}; |
| inst.create_info.add_layer(layer_name_0).add_layer(layer_name_1); |
| // "According to all known laws of aviation, there is no way that this should return VK_SUCCESS" |
| // This by accounts *should* return VK_ERROR_LAYER_NOT_PRESENT but due to a confluence of bad choices and backwards |
| // compatibility guarantee, returns VK_SUCCESS. |
| // REASON: To be able to 'load' a library in either 32 or 64 bit apps, the loader will just try to load both and ignore |
| // whichever library didn't match the current architecture. Because of this, the loader actually just flat out ignores |
| // errors and pretends they didn't load at all. |
| // TODO: add 32/64 bit field to layer manifests so that this issue doesn't occur, then implement logic to make the loader |
| // smart enough to tell when a layer that failed to load was due to the old behavior or not. (eg, don't report an error if |
| // a layer with the same name successfully loaded) |
| inst.CheckCreate(); |
| } |
| |
| TEST_F(EnumeratePhysicalDeviceGroups, OneCall) { |
| auto& driver = env->get_test_icd().SetMinICDInterfaceVersion(5); |
| // ICD contains 2 devices |
| driver.physical_devices.emplace_back("PhysicalDevice0"); |
| driver.physical_devices.emplace_back("PhysicalDevice1"); |
| // ICD contains 1 group, which contains both devices |
| driver.physical_device_groups.push_back({}); |
| driver.physical_device_groups.back() |
| .use_physical_device(driver.physical_devices[0]) |
| .use_physical_device(driver.physical_devices[1]); |
| uint32_t physical_device_count = 2; |
| |
| // Core function |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.set_api_version(1, 1, 0); |
| inst.CheckCreate(); |
| |
| auto physical_devices = std::vector<VkPhysicalDevice>(physical_device_count); |
| uint32_t returned_phys_dev_count = physical_device_count; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); |
| handle_assert_has_values(physical_devices); |
| |
| uint32_t group_count = static_cast<uint32_t>(driver.physical_device_groups.size()); |
| uint32_t returned_group_count = group_count; |
| VkPhysicalDeviceGroupProperties group_props{}; |
| group_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, &group_props)); |
| ASSERT_EQ(group_count, returned_group_count); |
| handle_assert_equal(group_props.physicalDevices[0], physical_devices[0]); |
| handle_assert_equal(group_props.physicalDevices[1], physical_devices[1]); |
| } |
| driver.AddInstanceExtension({"VK_KHR_device_group_creation"}); |
| // Extension |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.add_extension("VK_KHR_device_group_creation"); |
| inst.CheckCreate(); |
| |
| auto vkEnumeratePhysicalDeviceGroupsKHR = reinterpret_cast<PFN_vkEnumeratePhysicalDeviceGroupsKHR>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkEnumeratePhysicalDeviceGroupsKHR")); |
| |
| auto physical_devices = std::vector<VkPhysicalDevice>(physical_device_count); |
| uint32_t returned_phys_dev_count = physical_device_count; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); |
| handle_assert_has_values(physical_devices); |
| |
| uint32_t group_count = static_cast<uint32_t>(driver.physical_device_groups.size()); |
| uint32_t returned_group_count = group_count; |
| VkPhysicalDeviceGroupPropertiesKHR group_props{}; |
| group_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR; |
| ASSERT_EQ(VK_SUCCESS, vkEnumeratePhysicalDeviceGroupsKHR(inst, &returned_group_count, &group_props)); |
| ASSERT_EQ(group_count, returned_group_count); |
| handle_assert_equal(group_props.physicalDevices[0], physical_devices[0]); |
| handle_assert_equal(group_props.physicalDevices[1], physical_devices[1]); |
| } |
| } |
| |
| TEST_F(EnumeratePhysicalDeviceGroups, TwoCall) { |
| auto& driver = env->get_test_icd().SetMinICDInterfaceVersion(5); |
| // ICD contains 2 devices |
| driver.physical_devices.emplace_back("PhysicalDevice0"); |
| driver.physical_devices.emplace_back("PhysicalDevice1"); |
| // ICD contains 1 group, which contains both devices |
| driver.physical_device_groups.push_back({}); |
| driver.physical_device_groups.back() |
| .use_physical_device(driver.physical_devices[0]) |
| .use_physical_device(driver.physical_devices[1]); |
| uint32_t physical_device_count = 2; |
| |
| // Core function |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.set_api_version(1, 1, 0); |
| inst.CheckCreate(); |
| |
| auto physical_devices = std::vector<VkPhysicalDevice>(physical_device_count); |
| uint32_t returned_phys_dev_count = physical_device_count; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); |
| handle_assert_has_values(physical_devices); |
| |
| uint32_t group_count = static_cast<uint32_t>(driver.physical_device_groups.size()); |
| uint32_t returned_group_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, nullptr)); |
| ASSERT_EQ(group_count, returned_group_count); |
| |
| VkPhysicalDeviceGroupProperties group_props{}; |
| group_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, &group_props)); |
| ASSERT_EQ(group_count, returned_group_count); |
| handle_assert_equal(group_props.physicalDevices[0], physical_devices[0]); |
| handle_assert_equal(group_props.physicalDevices[1], physical_devices[1]); |
| } |
| driver.AddInstanceExtension({"VK_KHR_device_group_creation"}); |
| // Extension |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.add_extension("VK_KHR_device_group_creation"); |
| inst.CheckCreate(); |
| |
| auto physical_devices = std::vector<VkPhysicalDevice>(physical_device_count); |
| uint32_t returned_phys_dev_count = physical_device_count; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); |
| handle_assert_has_values(physical_devices); |
| |
| auto vkEnumeratePhysicalDeviceGroupsKHR = reinterpret_cast<PFN_vkEnumeratePhysicalDeviceGroupsKHR>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkEnumeratePhysicalDeviceGroupsKHR")); |
| |
| uint32_t group_count = static_cast<uint32_t>(driver.physical_device_groups.size()); |
| uint32_t returned_group_count = 0; |
| ASSERT_EQ(VK_SUCCESS, vkEnumeratePhysicalDeviceGroupsKHR(inst, &returned_group_count, nullptr)); |
| ASSERT_EQ(group_count, returned_group_count); |
| |
| VkPhysicalDeviceGroupPropertiesKHR group_props{}; |
| group_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR; |
| ASSERT_EQ(VK_SUCCESS, vkEnumeratePhysicalDeviceGroupsKHR(inst, &returned_group_count, &group_props)); |
| ASSERT_EQ(group_count, returned_group_count); |
| handle_assert_equal(group_props.physicalDevices[0], physical_devices[0]); |
| handle_assert_equal(group_props.physicalDevices[1], physical_devices[1]); |
| } |
| } |
| |
| TEST_F(EnumeratePhysicalDeviceGroups, TwoCallIncomplete) { |
| auto& driver = env->get_test_icd().SetMinICDInterfaceVersion(5); |
| // ICD contains 2 devices |
| driver.physical_devices.emplace_back("PhysicalDevice0"); |
| driver.physical_devices.emplace_back("PhysicalDevice1"); |
| // ICD contains 1 group, which contains both devices |
| driver.physical_device_groups.push_back({}); |
| driver.physical_device_groups.back() |
| .use_physical_device(driver.physical_devices[0]) |
| .use_physical_device(driver.physical_devices[1]); |
| |
| // Core function |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.set_api_version(1, 1, 0); |
| inst.CheckCreate(); |
| |
| uint32_t group_count = static_cast<uint32_t>(driver.physical_device_groups.size()); |
| uint32_t returned_group_count = 0; |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, nullptr)); |
| ASSERT_EQ(group_count, returned_group_count); |
| returned_group_count = 0; |
| |
| VkPhysicalDeviceGroupProperties group_props{}; |
| group_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES; |
| ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, &group_props)); |
| ASSERT_EQ(0, returned_group_count); |
| handle_assert_no_values(returned_group_count, group_props.physicalDevices); |
| } |
| driver.AddInstanceExtension({"VK_KHR_device_group_creation"}); |
| // Extension |
| { |
| InstWrapper inst{env->vulkan_functions}; |
| inst.create_info.add_extension("VK_KHR_device_group_creation"); |
| inst.CheckCreate(); |
| |
| auto vkEnumeratePhysicalDeviceGroupsKHR = reinterpret_cast<PFN_vkEnumeratePhysicalDeviceGroupsKHR>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkEnumeratePhysicalDeviceGroupsKHR")); |
| |
| uint32_t group_count = static_cast<uint32_t>(driver.physical_device_groups.size()); |
| uint32_t returned_group_count = 0; |
| ASSERT_EQ(VK_SUCCESS, vkEnumeratePhysicalDeviceGroupsKHR(inst, &returned_group_count, nullptr)); |
| ASSERT_EQ(group_count, returned_group_count); |
| returned_group_count = 0; |
| |
| VkPhysicalDeviceGroupPropertiesKHR group_props{}; |
| group_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR; |
| ASSERT_EQ(VK_INCOMPLETE, vkEnumeratePhysicalDeviceGroupsKHR(inst, &returned_group_count, &group_props)); |
| ASSERT_EQ(0, returned_group_count); |
| handle_assert_no_values(returned_group_count, group_props.physicalDevices); |
| } |
| } |
| |
| #if defined(__linux__) || defined(__FreeBSD__) |
| // Make sure the loader reports the correct message based on if USE_UNSAFE_FILE_SEARCH is set or not |
| TEST(EnvironmentVariables, NonSecureEnvVarLookup) { |
| SingleICDShim env(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| 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(); |
| |
| #if !defined(USE_UNSAFE_FILE_SEARCH) |
| ASSERT_FALSE(log.find("Loader is using non-secure environment variable lookup for")); |
| #else |
| ASSERT_TRUE(log.find("Loader is using non-secure environment variable lookup for")); |
| #endif |
| } |
| |
| // Check for proper handling of paths specified via environment variables. |
| TEST(EnvironmentVariables, XDG) { |
| // Set up a layer path that includes default and user-specified locations, |
| // so that the test app can find them. Include some badly specified elements as well. |
| // Need to redirect the 'home' directory |
| fs::path HOME = "/home/fake_home"; |
| set_env_var("HOME", HOME.str()); |
| set_env_var("XDG_CONFIG_DIRS", ":/tmp/goober:::::/tmp/goober/::::"); |
| set_env_var("XDG_CONFIG_HOME", ":/tmp/goober:::::/tmp/goober2/::::"); |
| set_env_var("XDG_DATA_DIRS", "::::/tmp/goober3:/tmp/goober4/with spaces:::"); |
| set_env_var("XDG_DATA_HOME", "::::/tmp/goober3:/tmp/goober4/with spaces:::"); |
| |
| SingleICDShim env{TestICDDetails{TEST_ICD_PATH_VERSION_6}}; |
| env.get_test_icd().physical_devices.push_back({}); |
| |
| InstWrapper inst{env.vulkan_functions}; |
| FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); |
| inst.CheckCreate(); |
| |
| auto check_paths = [](DebugUtilsLogger const& debug_log, ManifestCategory category, fs::path const& HOME) { |
| EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober/vulkan") / category_path_name(category)).str())); |
| EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober2/vulkan") / category_path_name(category)).str())); |
| EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober3/vulkan") / category_path_name(category)).str())); |
| EXPECT_TRUE(debug_log.find((fs::path("/tmp/goober4/with spaces/vulkan") / category_path_name(category)).str())); |
| }; |
| check_paths(env.debug_log, ManifestCategory::icd, HOME); |
| check_paths(env.debug_log, ManifestCategory::implicit_layer, HOME); |
| check_paths(env.debug_log, ManifestCategory::explicit_layer, HOME); |
| } |
| |
| // Check for proper handling of paths specified via environment variables. |
| TEST(EnvironmentVariables, VK_LAYER_PATH) { |
| // Set up a layer path that includes default and user-specified locations, |
| // so that the test app can find them. Include some badly specified elements as well. |
| // Need to redirect the 'home' directory |
| fs::path HOME = "/home/fake_home"; |
| set_env_var("HOME", HOME.str()); |
| std::string vk_layer_path = ":/tmp/carol::::/:"; |
| vk_layer_path += (HOME / "/ with spaces/:::::/tandy:").str(); |
| set_env_var("VK_LAYER_PATH", vk_layer_path); |
| |
| SingleICDShim env{TestICDDetails{TEST_ICD_PATH_VERSION_6}}; |
| env.get_test_icd().physical_devices.push_back({}); |
| env.platform_shim->redirect_path("/tmp/carol", env.explicit_layer_folder.location()); |
| const char* layer_name = "TestLayer"; |
| |
| ManifestLayer::LayerDescription description{}; |
| description.name = layer_name; |
| description.lib_path = TEST_LAYER_PATH_EXPORT_VERSION_2; |
| |
| ManifestLayer layer; |
| layer.layers.push_back(description); |
| env.AddExplicitLayer(layer, "test_layer.json"); |
| |
| InstWrapper inst{env.vulkan_functions}; |
| inst.create_info.add_layer(layer_name); |
| FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); |
| inst.CheckCreate(); |
| |
| // look for VK_LAYER_PATHS |
| EXPECT_TRUE(env.debug_log.find("/tmp/carol")); |
| EXPECT_TRUE(env.debug_log.find("/tandy")); |
| EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/").str())); |
| } |
| #endif |
| |
| TEST(ExtensionManual, ToolingProperties) { |
| VkPhysicalDeviceToolPropertiesEXT icd_tool_props{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT, |
| nullptr, |
| "FakeICDTool", |
| "version_0_0_0_1.b", |
| VK_TOOL_PURPOSE_VALIDATION_BIT_EXT, |
| "This tool does not exist", |
| "No-Layer"}; |
| { // No support in driver |
| SingleICDShim env{TestICDDetails{TEST_ICD_PATH_VERSION_6}}; |
| env.get_test_icd().physical_devices.push_back({}); |
| |
| InstWrapper inst{env.vulkan_functions}; |
| inst.CheckCreate(); |
| |
| auto phys_dev = inst.GetPhysDev(); |
| |
| auto getToolProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceToolPropertiesEXT>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceToolPropertiesEXT")); |
| handle_assert_has_value(getToolProperties); |
| |
| uint32_t tool_count = 0; |
| ASSERT_EQ(VK_SUCCESS, getToolProperties(phys_dev, &tool_count, nullptr)); |
| ASSERT_EQ(tool_count, 0); |
| } |
| { // extension is supported in driver |
| SingleICDShim env{TestICDDetails{TEST_ICD_PATH_VERSION_6}}; |
| env.get_test_icd().physical_devices.push_back({}); |
| env.get_test_icd().supports_tooling_info_ext = true; |
| env.get_test_icd().tooling_properties.push_back(icd_tool_props); |
| env.get_test_icd().physical_devices.back().extensions.push_back({VK_EXT_TOOLING_INFO_EXTENSION_NAME, 0}); |
| |
| InstWrapper inst{env.vulkan_functions}; |
| inst.CheckCreate(); |
| |
| auto phys_dev = inst.GetPhysDev(); |
| |
| auto getToolProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceToolPropertiesEXT>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceToolPropertiesEXT")); |
| handle_assert_has_value(getToolProperties); |
| uint32_t tool_count = 0; |
| ASSERT_EQ(VK_SUCCESS, getToolProperties(phys_dev, &tool_count, nullptr)); |
| ASSERT_EQ(tool_count, 1); |
| VkPhysicalDeviceToolPropertiesEXT props{}; |
| ASSERT_EQ(VK_SUCCESS, getToolProperties(phys_dev, &tool_count, &props)); |
| ASSERT_EQ(tool_count, 1); |
| string_eq(props.name, icd_tool_props.name); |
| } |
| } |