| /* |
| * Copyright (c) 2021-2022 The Khronos Group Inc. |
| * Copyright (c) 2021-2022 Valve Corporation |
| * Copyright (c) 2021-2022 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> |
| * Author: Mark Young <marky@lunarg.com> |
| */ |
| |
| #include "test_environment.h" |
| |
| // These tests are all instance extension tests that touch physical devices. This was |
| // before the idea that physical device extensions were more appropriately found in the |
| // list of device extensions. Because of that, all these tests need to support devices |
| // that don't support the extension and have a fallback path in the loader that needs |
| // validation. |
| |
| // Fill in random but valid data into the device properties struct for the current physical device |
| static void FillInRandomICDInfo(uint32_t& vendor_id, uint32_t& driver_vers) { |
| vendor_id = VK_MAKE_API_VERSION(0, rand() % 64, rand() % 255, rand() % 255); |
| driver_vers = VK_MAKE_API_VERSION(0, rand() % 64, rand() % 255, rand() % 255); |
| } |
| |
| // Fill in random but valid data into the device properties struct for the current physical device |
| static void FillInRandomDeviceProps(VkPhysicalDeviceProperties& props, uint32_t api_vers, uint32_t vendor, uint32_t driver_vers) { |
| props.apiVersion = api_vers; |
| props.driverVersion = driver_vers; |
| props.vendorID = vendor; |
| props.deviceID = (static_cast<uint32_t>(rand()) >> 4) + (static_cast<uint32_t>(rand()) << 2); |
| props.deviceType = static_cast<VkPhysicalDeviceType>(rand() % 5); |
| for (uint8_t idx = 0; idx < VK_UUID_SIZE; ++idx) { |
| props.pipelineCacheUUID[idx] = static_cast<uint8_t>(rand() % 255); |
| } |
| } |
| |
| // |
| // VK_KHR_get_physical_device_properties2 |
| // |
| |
| // Test vkGetPhysicalDeviceProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR")); |
| ASSERT_EQ(GetPhysDevProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR")); |
| ASSERT_EQ(GetPhysDevProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_0, 5, 123); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR")); |
| ASSERT_NE(GetPhysDevProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceProperties props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_device, &props); |
| VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; |
| GetPhysDevProps2(physical_device, &props2); |
| |
| // Both properties should match |
| ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); |
| ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); |
| ASSERT_EQ(props.vendorID, props2.properties.vendorID); |
| ASSERT_EQ(props.deviceID, props2.properties.deviceID); |
| ASSERT_EQ(props.deviceType, props2.properties.deviceType); |
| ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); |
| } |
| |
| // Test vkGetPhysicalDeviceProperties2 where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_1, 5, 123); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2")); |
| ASSERT_NE(GetPhysDevProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceProperties props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_device, &props); |
| VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; |
| GetPhysDevProps2(physical_device, &props2); |
| |
| // Both properties should match |
| ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); |
| ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); |
| ASSERT_EQ(props.vendorID, props2.properties.vendorID); |
| ASSERT_EQ(props.deviceID, props2.properties.deviceID); |
| ASSERT_EQ(props.deviceType, props2.properties.deviceType); |
| ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); |
| } |
| |
| // Test vkGetPhysicalDeviceProperties2 and vkGetPhysicalDeviceProperties2KHR where ICD is 1.0 and supports |
| // extension but the instance supports 1.1 and the extension |
| TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceSupports11) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_0)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_0, 5, 123); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2")); |
| ASSERT_NE(GetPhysDevProps2, nullptr); |
| |
| auto GetPhysDevProps2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR")); |
| ASSERT_NE(GetPhysDevProps2KHR, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceProperties props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_device, &props); |
| VkPhysicalDeviceProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; |
| GetPhysDevProps2(physical_device, &props2); |
| |
| // Both VkPhysicalDeviceProperties2 properties should match |
| ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); |
| ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); |
| ASSERT_EQ(props.vendorID, props2.properties.vendorID); |
| ASSERT_EQ(props.deviceID, props2.properties.deviceID); |
| ASSERT_EQ(props.deviceType, props2.properties.deviceType); |
| ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); |
| |
| VkPhysicalDeviceProperties2KHR props2KHR{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; |
| GetPhysDevProps2(physical_device, &props2KHR); |
| |
| // Both VkPhysicalDeviceProperties2KHR properties should match |
| ASSERT_EQ(props.apiVersion, props2KHR.properties.apiVersion); |
| ASSERT_EQ(props.driverVersion, props2KHR.properties.driverVersion); |
| ASSERT_EQ(props.vendorID, props2KHR.properties.vendorID); |
| ASSERT_EQ(props.deviceID, props2KHR.properties.deviceID); |
| ASSERT_EQ(props.deviceType, props2KHR.properties.deviceType); |
| ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2KHR.properties.pipelineCacheUUID, VK_UUID_SIZE)); |
| |
| ASSERT_FALSE(log.find("Emulating call in ICD")); |
| } |
| |
| // Test vkGetPhysicalDeviceProperties2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevProps2Mixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2")); |
| ASSERT_NE(GetPhysDevProps2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &props); |
| VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; |
| GetPhysDevProps2(physical_devices[dev], &props2); |
| |
| // Both properties should match |
| ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); |
| ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); |
| ASSERT_EQ(props.vendorID, props2.properties.vendorID); |
| ASSERT_EQ(props.deviceID, props2.properties.deviceID); |
| ASSERT_EQ(props.deviceType, props2.properties.deviceType); |
| ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); |
| } |
| } |
| |
| // Fill in random but valid data into the features struct for the current physical device |
| static void FillInRandomFeatures(VkPhysicalDeviceFeatures& feats) { |
| feats.robustBufferAccess = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.fullDrawIndexUint32 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.imageCubeArray = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.independentBlend = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.geometryShader = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.tessellationShader = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sampleRateShading = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.dualSrcBlend = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.logicOp = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.multiDrawIndirect = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.drawIndirectFirstInstance = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.depthClamp = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.depthBiasClamp = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.fillModeNonSolid = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.depthBounds = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.wideLines = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.largePoints = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.alphaToOne = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.multiViewport = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.samplerAnisotropy = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.textureCompressionETC2 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.textureCompressionASTC_LDR = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.textureCompressionBC = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.occlusionQueryPrecise = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.pipelineStatisticsQuery = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.vertexPipelineStoresAndAtomics = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.fragmentStoresAndAtomics = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderTessellationAndGeometryPointSize = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderImageGatherExtended = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderStorageImageExtendedFormats = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderStorageImageMultisample = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderStorageImageReadWithoutFormat = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderStorageImageWriteWithoutFormat = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderUniformBufferArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderSampledImageArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderStorageBufferArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderStorageImageArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderClipDistance = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderCullDistance = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderFloat64 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderInt64 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderInt16 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderResourceResidency = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.shaderResourceMinLod = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseBinding = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidencyBuffer = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidencyImage2D = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidencyImage3D = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidency2Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidency4Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidency8Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidency16Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.sparseResidencyAliased = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.variableMultisampleRate = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| feats.inheritedQueries = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; |
| } |
| |
| // Compare the contents of the feature structs |
| static bool CompareFeatures(const VkPhysicalDeviceFeatures& feats1, const VkPhysicalDeviceFeatures2& feats2) { |
| return feats1.robustBufferAccess == feats2.features.robustBufferAccess && |
| feats1.fullDrawIndexUint32 == feats2.features.fullDrawIndexUint32 && |
| feats1.imageCubeArray == feats2.features.imageCubeArray && feats1.independentBlend == feats2.features.independentBlend && |
| feats1.geometryShader == feats2.features.geometryShader && |
| feats1.tessellationShader == feats2.features.tessellationShader && |
| feats1.sampleRateShading == feats2.features.sampleRateShading && feats1.dualSrcBlend == feats2.features.dualSrcBlend && |
| feats1.logicOp == feats2.features.logicOp && feats1.multiDrawIndirect == feats2.features.multiDrawIndirect && |
| feats1.drawIndirectFirstInstance == feats2.features.drawIndirectFirstInstance && |
| feats1.depthClamp == feats2.features.depthClamp && feats1.depthBiasClamp == feats2.features.depthBiasClamp && |
| feats1.fillModeNonSolid == feats2.features.fillModeNonSolid && feats1.depthBounds == feats2.features.depthBounds && |
| feats1.wideLines == feats2.features.wideLines && feats1.largePoints == feats2.features.largePoints && |
| feats1.alphaToOne == feats2.features.alphaToOne && feats1.multiViewport == feats2.features.multiViewport && |
| feats1.samplerAnisotropy == feats2.features.samplerAnisotropy && |
| feats1.textureCompressionETC2 == feats2.features.textureCompressionETC2 && |
| feats1.textureCompressionASTC_LDR == feats2.features.textureCompressionASTC_LDR && |
| feats1.textureCompressionBC == feats2.features.textureCompressionBC && |
| feats1.occlusionQueryPrecise == feats2.features.occlusionQueryPrecise && |
| feats1.pipelineStatisticsQuery == feats2.features.pipelineStatisticsQuery && |
| feats1.vertexPipelineStoresAndAtomics == feats2.features.vertexPipelineStoresAndAtomics && |
| feats1.fragmentStoresAndAtomics == feats2.features.fragmentStoresAndAtomics && |
| feats1.shaderTessellationAndGeometryPointSize == feats2.features.shaderTessellationAndGeometryPointSize && |
| feats1.shaderImageGatherExtended == feats2.features.shaderImageGatherExtended && |
| feats1.shaderStorageImageExtendedFormats == feats2.features.shaderStorageImageExtendedFormats && |
| feats1.shaderStorageImageMultisample == feats2.features.shaderStorageImageMultisample && |
| feats1.shaderStorageImageReadWithoutFormat == feats2.features.shaderStorageImageReadWithoutFormat && |
| feats1.shaderStorageImageWriteWithoutFormat == feats2.features.shaderStorageImageWriteWithoutFormat && |
| feats1.shaderUniformBufferArrayDynamicIndexing == feats2.features.shaderUniformBufferArrayDynamicIndexing && |
| feats1.shaderSampledImageArrayDynamicIndexing == feats2.features.shaderSampledImageArrayDynamicIndexing && |
| feats1.shaderStorageBufferArrayDynamicIndexing == feats2.features.shaderStorageBufferArrayDynamicIndexing && |
| feats1.shaderStorageImageArrayDynamicIndexing == feats2.features.shaderStorageImageArrayDynamicIndexing && |
| feats1.shaderClipDistance == feats2.features.shaderClipDistance && |
| feats1.shaderCullDistance == feats2.features.shaderCullDistance && |
| feats1.shaderFloat64 == feats2.features.shaderFloat64 && feats1.shaderInt64 == feats2.features.shaderInt64 && |
| feats1.shaderInt16 == feats2.features.shaderInt16 && |
| feats1.shaderResourceResidency == feats2.features.shaderResourceResidency && |
| feats1.shaderResourceMinLod == feats2.features.shaderResourceMinLod && |
| feats1.sparseBinding == feats2.features.sparseBinding && |
| feats1.sparseResidencyBuffer == feats2.features.sparseResidencyBuffer && |
| feats1.sparseResidencyImage2D == feats2.features.sparseResidencyImage2D && |
| feats1.sparseResidencyImage3D == feats2.features.sparseResidencyImage3D && |
| feats1.sparseResidency2Samples == feats2.features.sparseResidency2Samples && |
| feats1.sparseResidency4Samples == feats2.features.sparseResidency4Samples && |
| feats1.sparseResidency8Samples == feats2.features.sparseResidency8Samples && |
| feats1.sparseResidency16Samples == feats2.features.sparseResidency16Samples && |
| feats1.sparseResidencyAliased == feats2.features.sparseResidencyAliased && |
| feats1.variableMultisampleRate == feats2.features.variableMultisampleRate && |
| feats1.inheritedQueries == feats2.features.inheritedQueries; |
| } |
| |
| // Test vkGetPhysicalDeviceFeatures2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevFeats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR")); |
| ASSERT_EQ(GetPhysDevFeats2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceFeatures2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevFeatsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysDevFeats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR")); |
| ASSERT_EQ(GetPhysDevFeats2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceFeatures2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevFeats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR")); |
| ASSERT_NE(GetPhysDevFeats2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceFeatures feats{}; |
| instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); |
| VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR}; |
| GetPhysDevFeats2(physical_device, &feats2); |
| ASSERT_TRUE(CompareFeatures(feats, feats2)); |
| } |
| |
| // Test vkGetPhysicalDeviceFeatures2 where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevFeats2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevFeats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2")); |
| ASSERT_NE(GetPhysDevFeats2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceFeatures feats{}; |
| instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); |
| VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; |
| GetPhysDevFeats2(physical_device, &feats2); |
| ASSERT_TRUE(CompareFeatures(feats, feats2)); |
| } |
| |
| // Test vkGetPhysicalDeviceFeatures2 and vkGetPhysicalDeviceFeatures2KHR where ICD is 1.0 and supports |
| // extension but the instance supports 1.1 and the extension |
| TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceSupports11) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_0)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevFeats2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR")); |
| ASSERT_NE(GetPhysDevFeats2KHR, nullptr); |
| |
| auto GetPhysDevFeats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2")); |
| ASSERT_NE(GetPhysDevFeats2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceFeatures feats{}; |
| instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); |
| |
| VkPhysicalDeviceFeatures2KHR feats2KHR{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR}; |
| GetPhysDevFeats2KHR(physical_device, &feats2KHR); |
| ASSERT_TRUE(CompareFeatures(feats, feats2KHR)); |
| |
| VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; |
| GetPhysDevFeats2(physical_device, &feats2); |
| ASSERT_TRUE(CompareFeatures(feats, feats2)); |
| |
| ASSERT_FALSE(log.find("Emulating call in ICD")); |
| } |
| |
| // Test vkGetPhysicalDeviceFeatures2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevFeatsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomFeatures(cur_dev.features); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevFeats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2")); |
| ASSERT_NE(GetPhysDevFeats2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceFeatures feats{}; |
| instance->vkGetPhysicalDeviceFeatures(physical_devices[dev], &feats); |
| VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; |
| GetPhysDevFeats2(physical_devices[dev], &feats2); |
| ASSERT_TRUE(CompareFeatures(feats, feats2)); |
| } |
| } |
| |
| // Fill in random but valid data into the format properties struct for the current physical device |
| static void FillInRandomFormatProperties(std::vector<VkFormatProperties>& props) { |
| props.resize(5); |
| for (uint8_t form = 0; form < 5; ++form) { |
| props[form].bufferFeatures = static_cast<VkFormatFeatureFlags>(rand()); |
| props[form].linearTilingFeatures = static_cast<VkFormatFeatureFlags>(rand()); |
| props[form].optimalTilingFeatures = static_cast<VkFormatFeatureFlags>(rand()); |
| } |
| } |
| |
| // Test vkGetPhysicalDeviceFormatProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR")); |
| ASSERT_EQ(GetPhysDevFormatProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceFormatProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevFormatPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysDevFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR")); |
| ASSERT_EQ(GetPhysDevFormatProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceFormatProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR")); |
| ASSERT_NE(GetPhysDevFormatProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkFormatProperties props{}; |
| instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); |
| VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| GetPhysDevFormatProps2(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); |
| |
| ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); |
| ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); |
| ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); |
| } |
| |
| // Test vkGetPhysicalDeviceFormatProperties2 where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevFormatProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2")); |
| ASSERT_NE(GetPhysDevFormatProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkFormatProperties props{}; |
| instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); |
| VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| GetPhysDevFormatProps2(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); |
| |
| ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); |
| ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); |
| ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); |
| } |
| |
| // Test vkGetPhysicalDeviceFormatProperties2 and vkGetPhysicalDeviceFormatProperties2KHR where ICD is 1.0 and supports |
| // extension but the instance supports 1.1 and the extension |
| TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceSupports11) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2")); |
| ASSERT_NE(GetPhysDevFormatProps2, nullptr); |
| |
| auto GetPhysDevFormatProps2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR")); |
| ASSERT_NE(GetPhysDevFormatProps2KHR, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkFormatProperties props{}; |
| instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); |
| VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| GetPhysDevFormatProps2(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); |
| |
| ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); |
| ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); |
| ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); |
| |
| VkFormatProperties2KHR props2KHR{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| GetPhysDevFormatProps2KHR(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2KHR); |
| |
| ASSERT_EQ(props.bufferFeatures, props2KHR.formatProperties.bufferFeatures); |
| ASSERT_EQ(props.linearTilingFeatures, props2KHR.formatProperties.linearTilingFeatures); |
| ASSERT_EQ(props.optimalTilingFeatures, props2KHR.formatProperties.optimalTilingFeatures); |
| |
| ASSERT_FALSE(log.find("Emulating call in ICD")); |
| } |
| |
| // Test vkGetPhysicalDeviceFormatProperties2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevFormatPropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomFormatProperties(cur_dev.format_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2")); |
| ASSERT_NE(GetPhysDevFormatProps2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkFormat format = static_cast<VkFormat>((dev + 1) % 5); |
| VkFormatProperties props{}; |
| instance->vkGetPhysicalDeviceFormatProperties(physical_devices[dev], format, &props); |
| VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| GetPhysDevFormatProps2(physical_devices[dev], format, &props2); |
| |
| ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); |
| ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); |
| ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); |
| } |
| } |
| |
| // Fill in random but valid data into the image format data struct for the current physical device |
| static void FillInRandomImageFormatData(VkImageFormatProperties& props) { |
| props.maxExtent = {static_cast<uint32_t>(rand() % 512), static_cast<uint32_t>(rand() % 512), |
| static_cast<uint32_t>(rand() % 512)}; |
| props.maxMipLevels = static_cast<uint32_t>(1 << (rand() % 16)); |
| props.maxArrayLayers = static_cast<uint32_t>(1 << (rand() % 16)); |
| props.sampleCounts = static_cast<VkSampleCountFlags>(1 << (rand() % 7)); |
| props.maxResourceSize = static_cast<uint64_t>(rand()); |
| } |
| |
| // Test vkGetPhysicalDeviceImageFormatProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR")); |
| ASSERT_EQ(GetPhysDevImageFormatProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceImageFormatProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevImageFormatPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysDevImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR")); |
| ASSERT_EQ(GetPhysDevImageFormatProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceImageFormatProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR")); |
| ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkImageFormatProperties props{}; |
| ASSERT_EQ(VK_SUCCESS, |
| instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); |
| |
| VkPhysicalDeviceImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| 0, // usage |
| 0, // flags |
| }; |
| VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_device, &info2, &props2)); |
| |
| ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); |
| ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); |
| ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); |
| ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); |
| ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); |
| ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); |
| ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); |
| } |
| |
| // Test vkGetPhysicalDeviceImageFormatProperties2 where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2")); |
| ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkImageFormatProperties props{}; |
| ASSERT_EQ(VK_SUCCESS, |
| instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); |
| |
| VkPhysicalDeviceImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| 0, // usage |
| 0, // flags |
| }; |
| |
| VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_device, &info2, &props2)); |
| |
| ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); |
| ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); |
| ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); |
| ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); |
| ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); |
| ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); |
| ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); |
| } |
| |
| // Test vkGetPhysicalDeviceImageFormatProperties2 and vkGetPhysicalDeviceImageFormatProperties2KHR where instance supports, an ICD, |
| // and a device under that ICD also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceSupports11) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2")); |
| ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); |
| |
| auto GetPhysDevImageFormatProps2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR")); |
| ASSERT_NE(GetPhysDevImageFormatProps2KHR, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkImageFormatProperties props{}; |
| ASSERT_EQ(VK_SUCCESS, |
| instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); |
| |
| VkPhysicalDeviceImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| 0, // usage |
| 0, // flags |
| }; |
| |
| VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_device, &info2, &props2)); |
| |
| ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); |
| ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); |
| ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); |
| ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); |
| ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); |
| ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); |
| ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); |
| |
| VkImageFormatProperties2KHR props2KHR{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2KHR(physical_device, &info2, &props2KHR)); |
| |
| ASSERT_EQ(props.maxExtent.width, props2KHR.imageFormatProperties.maxExtent.width); |
| ASSERT_EQ(props.maxExtent.height, props2KHR.imageFormatProperties.maxExtent.height); |
| ASSERT_EQ(props.maxExtent.depth, props2KHR.imageFormatProperties.maxExtent.depth); |
| ASSERT_EQ(props.maxMipLevels, props2KHR.imageFormatProperties.maxMipLevels); |
| ASSERT_EQ(props.maxArrayLayers, props2KHR.imageFormatProperties.maxArrayLayers); |
| ASSERT_EQ(props.sampleCounts, props2KHR.imageFormatProperties.sampleCounts); |
| ASSERT_EQ(props.maxResourceSize, props2KHR.imageFormatProperties.maxResourceSize); |
| |
| ASSERT_FALSE(log.find("Emulating call in ICD")); |
| } |
| |
| // Test vkGetPhysicalDeviceImageFormatProperties2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevImageFormatPropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomImageFormatData(cur_dev.image_format_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2")); |
| ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkImageFormatProperties props{}; |
| ASSERT_EQ(VK_SUCCESS, |
| instance->vkGetPhysicalDeviceImageFormatProperties(physical_devices[dev], VK_FORMAT_R4G4_UNORM_PACK8, |
| VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); |
| |
| VkPhysicalDeviceImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| 0, // usage |
| 0, // flags |
| }; |
| VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_devices[dev], &info2, &props2)); |
| |
| ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); |
| ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); |
| ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); |
| ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); |
| ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); |
| ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); |
| ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); |
| } |
| } |
| |
| // Test vkGetPhysicalDeviceMemoryProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevMemoryProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2KHR")); |
| ASSERT_EQ(GetPhysDevMemoryProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceMemoryProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevMemoryPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysDevMemoryProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2KHR")); |
| ASSERT_EQ(GetPhysDevMemoryProps2, nullptr); |
| } |
| |
| // Fill in random but valid data into the memory data struct for the current physical device |
| static void FillInRandomMemoryData(VkPhysicalDeviceMemoryProperties& props) { |
| props.memoryTypeCount = (rand() % 7) + 1; |
| props.memoryHeapCount = (rand() % 7) + 1; |
| for (uint32_t i = 0; i < props.memoryHeapCount; ++i) { |
| props.memoryHeaps[i].size = (rand() % 728) + (rand() % 728) + 1; |
| props.memoryHeaps[i].flags = (rand() % 2) + 1; |
| } |
| for (uint32_t i = 0; i < props.memoryTypeCount; ++i) { |
| props.memoryTypes[i].propertyFlags = static_cast<VkMemoryPropertyFlags>((rand() % 2) + 1); |
| props.memoryTypes[i].heapIndex = rand() % props.memoryHeapCount; |
| } |
| } |
| |
| // Compare the memory structs |
| static bool CompareMemoryData(const VkPhysicalDeviceMemoryProperties& props1, const VkPhysicalDeviceMemoryProperties2& props2) { |
| bool equal = true; |
| equal = equal && props1.memoryTypeCount == props2.memoryProperties.memoryTypeCount; |
| equal = equal && props1.memoryHeapCount == props2.memoryProperties.memoryHeapCount; |
| for (uint32_t i = 0; i < props1.memoryHeapCount; ++i) { |
| equal = equal && props1.memoryHeaps[i].size == props2.memoryProperties.memoryHeaps[i].size; |
| equal = equal && props1.memoryHeaps[i].flags == props2.memoryProperties.memoryHeaps[i].flags; |
| } |
| for (uint32_t i = 0; i < props1.memoryTypeCount; ++i) { |
| equal = equal && props1.memoryTypes[i].propertyFlags == props2.memoryProperties.memoryTypes[i].propertyFlags; |
| equal = equal && props1.memoryTypes[i].heapIndex == props2.memoryProperties.memoryTypes[i].heapIndex; |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceMemoryProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevMemoryProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2KHR")); |
| ASSERT_NE(GetPhysDevMemoryProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceMemoryProperties props{}; |
| instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); |
| |
| VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; |
| GetPhysDevMemoryProps2(physical_device, &props2); |
| ASSERT_TRUE(CompareMemoryData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceMemoryProperties2 where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevMemoryProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2")); |
| ASSERT_NE(GetPhysDevMemoryProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceMemoryProperties props{}; |
| instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); |
| |
| VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; |
| GetPhysDevMemoryProps2(physical_device, &props2); |
| ASSERT_TRUE(CompareMemoryData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceMemoryProperties2 and vkGetPhysicalDeviceMemoryProperties2KHR where ICD is 1.0 and supports |
| // extension but the instance supports 1.1 and the extension |
| TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceSupports11) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevMemoryProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2")); |
| ASSERT_NE(GetPhysDevMemoryProps2, nullptr); |
| |
| auto GetPhysDevMemoryProps2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2KHR")); |
| ASSERT_NE(GetPhysDevMemoryProps2KHR, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceMemoryProperties props{}; |
| instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); |
| |
| VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; |
| GetPhysDevMemoryProps2(physical_device, &props2); |
| ASSERT_TRUE(CompareMemoryData(props, props2)); |
| |
| VkPhysicalDeviceMemoryProperties2KHR props2KHR{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR}; |
| GetPhysDevMemoryProps2KHR(physical_device, &props2KHR); |
| ASSERT_TRUE(CompareMemoryData(props, props2KHR)); |
| |
| ASSERT_FALSE(log.find("Emulating call in ICD")); |
| } |
| // Test vkGetPhysicalDeviceMemoryProperties2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevMemoryPropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomMemoryData(cur_dev.memory_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevMemoryProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2")); |
| ASSERT_NE(GetPhysDevMemoryProps2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceMemoryProperties props{}; |
| instance->vkGetPhysicalDeviceMemoryProperties(physical_devices[dev], &props); |
| |
| VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; |
| GetPhysDevMemoryProps2(physical_devices[dev], &props2); |
| ASSERT_TRUE(CompareMemoryData(props, props2)); |
| } |
| } |
| |
| // Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevQueueFamilyProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR")); |
| ASSERT_EQ(GetPhysDevQueueFamilyProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysDevQueueFamilyProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR")); |
| ASSERT_EQ(GetPhysDevQueueFamilyProps2, nullptr); |
| } |
| |
| // Fill in random but valid data into the queue family data struct for the current physical device |
| static uint32_t FillInRandomQueueFamilyData(std::vector<MockQueueFamilyProperties>& props) { |
| props.resize((rand() % 4) + 1); |
| for (uint32_t i = 0; i < props.size(); ++i) { |
| props[i].properties.queueFlags = (rand() % 30) + 1; |
| props[i].properties.queueCount = (rand() % 7) + 1; |
| props[i].properties.timestampValidBits = (rand() % 30) + 7; |
| props[i].properties.minImageTransferGranularity.width = (rand() % 30) + 1; |
| props[i].properties.minImageTransferGranularity.height = (rand() % 30) + 1; |
| props[i].properties.minImageTransferGranularity.depth = (rand() % 30) + 1; |
| props[i].support_present = rand() % 2 == 0; |
| } |
| return static_cast<uint32_t>(props.size()); |
| } |
| |
| // Compare the queue family structs |
| static bool CompareQueueFamilyData(const std::vector<VkQueueFamilyProperties>& props1, |
| const std::vector<VkQueueFamilyProperties2>& props2) { |
| if (props1.size() != props2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < props1.size(); ++i) { |
| equal = equal && props1[i].queueFlags == props2[i].queueFamilyProperties.queueFlags; |
| equal = equal && props1[i].queueCount == props2[i].queueFamilyProperties.queueCount; |
| equal = equal && props1[i].timestampValidBits == props2[i].queueFamilyProperties.timestampValidBits; |
| equal = equal && |
| props1[i].minImageTransferGranularity.width == props2[i].queueFamilyProperties.minImageTransferGranularity.width; |
| equal = equal && |
| props1[i].minImageTransferGranularity.height == props2[i].queueFamilyProperties.minImageTransferGranularity.height; |
| equal = equal && |
| props1[i].minImageTransferGranularity.depth == props2[i].queueFamilyProperties.minImageTransferGranularity.depth; |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevQueueFamilyProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR")); |
| ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| uint32_t ret_fam_1 = 0; |
| std::vector<VkQueueFamilyProperties> props{}; |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); |
| ASSERT_EQ(num_fam, ret_fam_1); |
| props.resize(ret_fam_1); |
| |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); |
| |
| std::vector<VkQueueFamilyProperties2> props2{}; |
| uint32_t ret_fam_2 = 0; |
| GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, nullptr); |
| ASSERT_EQ(ret_fam_1, ret_fam_2); |
| props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); |
| GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, props2.data()); |
| ASSERT_TRUE(CompareQueueFamilyData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceQueueFamilyProperties2 where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevQueueFamilyProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2")); |
| ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| uint32_t ret_fam_1 = 0; |
| std::vector<VkQueueFamilyProperties> props{}; |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); |
| ASSERT_EQ(num_fam, ret_fam_1); |
| props.resize(ret_fam_1); |
| |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); |
| |
| std::vector<VkQueueFamilyProperties2> props2{}; |
| uint32_t ret_fam_2 = 0; |
| GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, nullptr); |
| ASSERT_EQ(ret_fam_1, ret_fam_2); |
| props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); |
| GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, props2.data()); |
| ASSERT_TRUE(CompareQueueFamilyData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceQueueFamilyProperties2 and vkGetPhysicalDeviceQueueFamilyProperties2KHR where ICD is 1.0 and supports |
| // extension but the instance supports 1.1 and the extension |
| TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceSupports11) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevQueueFamilyProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2")); |
| ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); |
| |
| auto GetPhysDevQueueFamilyProps2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR")); |
| ASSERT_NE(GetPhysDevQueueFamilyProps2KHR, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| uint32_t ret_fam_1 = 0; |
| std::vector<VkQueueFamilyProperties> props{}; |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); |
| ASSERT_EQ(num_fam, ret_fam_1); |
| props.resize(ret_fam_1); |
| |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); |
| |
| std::vector<VkQueueFamilyProperties2> props2{}; |
| uint32_t ret_fam_2 = 0; |
| GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, nullptr); |
| ASSERT_EQ(ret_fam_1, ret_fam_2); |
| props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); |
| GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, props2.data()); |
| ASSERT_TRUE(CompareQueueFamilyData(props, props2)); |
| |
| std::vector<VkQueueFamilyProperties2KHR> props2KHR{}; |
| uint32_t ret_fam_2_khr = 0; |
| GetPhysDevQueueFamilyProps2KHR(physical_device, &ret_fam_2_khr, nullptr); |
| ASSERT_EQ(ret_fam_1, ret_fam_2_khr); |
| props2KHR.resize(ret_fam_2_khr, VkQueueFamilyProperties2KHR{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR}); |
| GetPhysDevQueueFamilyProps2KHR(physical_device, &ret_fam_2_khr, props2KHR.data()); |
| ASSERT_TRUE(CompareQueueFamilyData(props, props2KHR)); |
| |
| ASSERT_FALSE(log.find("Emulating call in ICD")); |
| } |
| |
| // Test vkGetPhysicalDeviceQueueFamilyProperties2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyPropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomQueueFamilyData(cur_dev.queue_family_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevQueueFamilyProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2")); |
| ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| uint32_t ret_fam_1 = 0; |
| std::vector<VkQueueFamilyProperties> props{}; |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[dev], &ret_fam_1, nullptr); |
| props.resize(ret_fam_1); |
| instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[dev], &ret_fam_1, props.data()); |
| |
| std::vector<VkQueueFamilyProperties2> props2{}; |
| uint32_t ret_fam_2 = 0; |
| GetPhysDevQueueFamilyProps2(physical_devices[dev], &ret_fam_2, nullptr); |
| ASSERT_EQ(ret_fam_1, ret_fam_2); |
| props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); |
| GetPhysDevQueueFamilyProps2(physical_devices[dev], &ret_fam_2, props2.data()); |
| ASSERT_TRUE(CompareQueueFamilyData(props, props2)); |
| } |
| } |
| |
| // Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevSparseImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR")); |
| ASSERT_EQ(GetPhysDevSparseImageFormatProps2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysDevSparseImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR")); |
| ASSERT_EQ(GetPhysDevSparseImageFormatProps2, nullptr); |
| } |
| |
| // Fill in random but valid data into the sparse image format data struct for the current physical device |
| static void FillInRandomSparseImageFormatData(std::vector<VkSparseImageFormatProperties>& props) { |
| props.resize((rand() % 4) + 1); |
| for (uint32_t i = 0; i < props.size(); ++i) { |
| props[i].aspectMask = static_cast<VkImageAspectFlags>((rand() % 0x7FE) + 1); |
| props[i].imageGranularity = {static_cast<uint32_t>(rand() % 512), static_cast<uint32_t>(rand() % 512), |
| static_cast<uint32_t>(rand() % 512)}; |
| props[i].flags = static_cast<VkSparseImageFormatFlags>((rand() % 6) + 1); |
| } |
| } |
| |
| // Compare the sparse image format structs |
| static bool CompareSparseImageFormatData(const std::vector<VkSparseImageFormatProperties>& props1, |
| const std::vector<VkSparseImageFormatProperties2>& props2) { |
| if (props1.size() != props2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < props1.size(); ++i) { |
| equal = equal && props1[i].aspectMask == props2[i].properties.aspectMask; |
| equal = equal && props1[i].imageGranularity.width == props2[i].properties.imageGranularity.width; |
| equal = equal && props1[i].imageGranularity.height == props2[i].properties.imageGranularity.height; |
| equal = equal && props1[i].imageGranularity.depth == props2[i].properties.imageGranularity.depth; |
| equal = equal && props1[i].flags == props2[i].properties.flags; |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevSparseImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR")); |
| ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkSparseImageFormatProperties> props{}; |
| uint32_t sparse_count_1 = 0; |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); |
| ASSERT_NE(sparse_count_1, 0); |
| props.resize(sparse_count_1); |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); |
| ASSERT_NE(sparse_count_1, 0); |
| |
| VkPhysicalDeviceSparseImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_SAMPLE_COUNT_4_BIT, // samples |
| VK_IMAGE_USAGE_STORAGE_BIT, // usage |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| }; |
| std::vector<VkSparseImageFormatProperties2> props2{}; |
| uint32_t sparse_count_2 = 0; |
| GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, nullptr); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); |
| GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, props2.data()); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceSparseImageFormatProperties2 where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevSparseImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2")); |
| ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkSparseImageFormatProperties> props{}; |
| uint32_t sparse_count_1 = 0; |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); |
| ASSERT_NE(sparse_count_1, 0); |
| props.resize(sparse_count_1); |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); |
| ASSERT_NE(sparse_count_1, 0); |
| |
| VkPhysicalDeviceSparseImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_SAMPLE_COUNT_4_BIT, // samples |
| VK_IMAGE_USAGE_STORAGE_BIT, // usage |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| }; |
| std::vector<VkSparseImageFormatProperties2> props2{}; |
| uint32_t sparse_count_2 = 0; |
| GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, nullptr); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); |
| GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, props2.data()); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceSparseImageFormatProperties2 and vkGetPhysicalDeviceSparseImageFormatProperties2KHR where ICD is 1.0 and |
| // supports extension but the instance supports 1.1 and the extension |
| TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceSupports11) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.create_info.add_extensions( |
| {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto GetPhysDevSparseImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2")); |
| ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); |
| |
| auto GetPhysDevSparseImageFormatProps2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR")); |
| ASSERT_NE(GetPhysDevSparseImageFormatProps2KHR, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkSparseImageFormatProperties> props{}; |
| uint32_t sparse_count_1 = 0; |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); |
| ASSERT_NE(sparse_count_1, 0); |
| props.resize(sparse_count_1); |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, |
| VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); |
| ASSERT_NE(sparse_count_1, 0); |
| |
| VkPhysicalDeviceSparseImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_SAMPLE_COUNT_4_BIT, // samples |
| VK_IMAGE_USAGE_STORAGE_BIT, // usage |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| }; |
| std::vector<VkSparseImageFormatProperties2> props2{}; |
| uint32_t sparse_count_2 = 0; |
| GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, nullptr); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); |
| GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, props2.data()); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); |
| |
| std::vector<VkSparseImageFormatProperties2KHR> props2KHR{}; |
| uint32_t sparse_count_2_khr = 0; |
| GetPhysDevSparseImageFormatProps2KHR(physical_device, &info2, &sparse_count_2_khr, nullptr); |
| ASSERT_EQ(sparse_count_1, sparse_count_2_khr); |
| props2KHR.resize(sparse_count_2, VkSparseImageFormatProperties2KHR{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR}); |
| GetPhysDevSparseImageFormatProps2KHR(physical_device, &info2, &sparse_count_2_khr, props2KHR.data()); |
| ASSERT_EQ(sparse_count_1, sparse_count_2_khr); |
| ASSERT_TRUE(CompareSparseImageFormatData(props, props2KHR)); |
| |
| ASSERT_FALSE(log.find("Emulating call in ICD")); |
| } |
| |
| // Test vkGetPhysicalDeviceSparseImageFormatProperties2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatPropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomSparseImageFormatData(cur_dev.sparse_image_format_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysDevSparseImageFormatProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2")); |
| ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| std::vector<VkSparseImageFormatProperties> props{}; |
| uint32_t sparse_count_1 = 0; |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties( |
| physical_devices[dev], VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); |
| ASSERT_NE(sparse_count_1, 0); |
| props.resize(sparse_count_1); |
| instance->vkGetPhysicalDeviceSparseImageFormatProperties( |
| physical_devices[dev], VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, |
| VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); |
| ASSERT_NE(sparse_count_1, 0); |
| |
| VkPhysicalDeviceSparseImageFormatInfo2 info2{ |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType |
| nullptr, // pNext |
| VK_FORMAT_R4G4_UNORM_PACK8, // format |
| VK_IMAGE_TYPE_2D, // type |
| VK_SAMPLE_COUNT_4_BIT, // samples |
| VK_IMAGE_USAGE_STORAGE_BIT, // usage |
| VK_IMAGE_TILING_OPTIMAL, // tiling |
| }; |
| std::vector<VkSparseImageFormatProperties2> props2{}; |
| uint32_t sparse_count_2 = 0; |
| GetPhysDevSparseImageFormatProps2(physical_devices[dev], &info2, &sparse_count_2, nullptr); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); |
| GetPhysDevSparseImageFormatProps2(physical_devices[dev], &info2, &sparse_count_2, props2.data()); |
| ASSERT_EQ(sparse_count_1, sparse_count_2); |
| ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); |
| } |
| } |
| |
| // |
| // VK_KHR_external_memory_capabilities |
| // |
| |
| // Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalBufferProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceExternalBufferProperties, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceExternalBufferProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceExternalBufferProperties, nullptr); |
| } |
| |
| // Fill in random but valid data into the external memorydata struct for the current physical device |
| static void FillInRandomExtMemoryData(VkExternalMemoryProperties& props) { |
| props.externalMemoryFeatures = static_cast<VkExternalMemoryFeatureFlags>((rand() % 6) + 1); |
| props.exportFromImportedHandleTypes = static_cast<VkExternalMemoryHandleTypeFlags>((rand() % 0x1FFE) + 1); |
| props.compatibleHandleTypes = static_cast<VkExternalMemoryHandleTypeFlags>((rand() % 0x1FFE) + 1); |
| } |
| |
| // Compare the external memory data structs |
| static bool CompareExtMemoryData(const VkExternalMemoryProperties& props1, const VkExternalMemoryProperties& props2, |
| bool supported = true) { |
| bool equal = true; |
| if (supported) { |
| equal = equal && props1.externalMemoryFeatures == props2.externalMemoryFeatures; |
| equal = equal && props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes; |
| equal = equal && props1.compatibleHandleTypes == props2.compatibleHandleTypes; |
| } else { |
| equal = equal && 0 == props2.externalMemoryFeatures; |
| equal = equal && 0 == props2.exportFromImportedHandleTypes; |
| equal = equal && 0 == props2.compatibleHandleTypes; |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalBufferProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceExternalBufferProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceExternalBufferInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR}; |
| VkExternalBufferPropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR}; |
| GetPhysicalDeviceExternalBufferProperties(physical_device, &info, &props); |
| ASSERT_TRUE(CompareExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties, |
| props.externalMemoryProperties)); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalBufferProperties where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0}); |
| FillInRandomExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalBufferProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalBufferProperties>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalBufferProperties")); |
| ASSERT_NE(GetPhysicalDeviceExternalBufferProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO}; |
| VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES}; |
| GetPhysicalDeviceExternalBufferProperties(physical_device, &info, &props); |
| ASSERT_TRUE(CompareExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties, |
| props.externalMemoryProperties)); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalBufferProperties where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomExtMemoryData(cur_dev.external_memory_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalBufferProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalBufferProperties>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalBufferProperties")); |
| ASSERT_NE(GetPhysicalDeviceExternalBufferProperties, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO}; |
| VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES}; |
| GetPhysicalDeviceExternalBufferProperties(physical_devices[dev], &info, &props); |
| // No driver support for extension or 1.1 for ICD 1, all others support |
| ASSERT_TRUE(CompareExtMemoryData(cur_dev.external_memory_properties, props.externalMemoryProperties, icd != 1)); |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // |
| // VK_KHR_external_semaphore_capabilities |
| // |
| |
| // Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalSemaphoreProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceExternalSemaphoreProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); |
| } |
| |
| // Fill in random but valid data into the external semaphore data struct for the current physical device |
| static void FillInRandomExtSemData(VkExternalSemaphoreProperties& props) { |
| props.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES; |
| props.pNext = nullptr; |
| props.exportFromImportedHandleTypes = static_cast<VkExternalSemaphoreHandleTypeFlags>((rand() % 0xFFF) + 1); |
| props.compatibleHandleTypes = static_cast<VkExternalSemaphoreHandleTypeFlags>((rand() % 0xFFF) + 1); |
| props.externalSemaphoreFeatures = static_cast<VkExternalSemaphoreFeatureFlags>((rand() % 0xFFF) + 1); |
| } |
| |
| // Compare the external semaphore data structs |
| static bool CompareExtSemaphoreData(const VkExternalSemaphoreProperties& props1, const VkExternalSemaphoreProperties& props2, |
| bool supported = true) { |
| bool equal = true; |
| if (supported) { |
| equal = equal && props1.externalSemaphoreFeatures == props2.externalSemaphoreFeatures; |
| equal = equal && props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes; |
| equal = equal && props1.compatibleHandleTypes == props2.compatibleHandleTypes; |
| } else { |
| equal = equal && 0 == props2.externalSemaphoreFeatures; |
| equal = equal && 0 == props2.exportFromImportedHandleTypes; |
| equal = equal && 0 == props2.compatibleHandleTypes; |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomExtSemData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalSemaphoreProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceExternalSemaphoreInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR}; |
| VkExternalSemaphorePropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR}; |
| GetPhysicalDeviceExternalSemaphoreProperties(physical_device, &info, &props); |
| ASSERT_TRUE(CompareExtSemaphoreData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props)); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalSemaphoreProperties where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0}); |
| FillInRandomExtSemData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalSemaphoreProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphoreProperties>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalSemaphoreProperties")); |
| ASSERT_NE(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO}; |
| VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES}; |
| GetPhysicalDeviceExternalSemaphoreProperties(physical_device, &info, &props); |
| ASSERT_TRUE(CompareExtSemaphoreData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props)); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalSemaphoreProperties where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomExtSemData(cur_dev.external_semaphore_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalSemaphoreProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphoreProperties>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalSemaphoreProperties")); |
| ASSERT_NE(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO}; |
| VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES}; |
| GetPhysicalDeviceExternalSemaphoreProperties(physical_devices[dev], &info, &props); |
| // No driver support for extension or 1.1 for ICD 1, all others support |
| ASSERT_TRUE(CompareExtSemaphoreData(cur_dev.external_semaphore_properties, props, icd != 1)); |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // |
| // VK_KHR_external_fence_capabilities |
| // |
| |
| // Test vkGetPhysicalDeviceExternalFencePropertiesKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalFenceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceExternalFenceProperties, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalFencePropertiesKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceExternalFenceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceExternalFenceProperties, nullptr); |
| } |
| |
| // Fill in random but valid data into the external fence data struct for the current physical device |
| static void FillInRandomExtFenceData(VkExternalFenceProperties& props) { |
| props.sType = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES; |
| props.pNext = nullptr; |
| props.exportFromImportedHandleTypes = static_cast<VkExternalFenceHandleTypeFlags>((rand() % 0xFFF) + 1); |
| props.compatibleHandleTypes = static_cast<VkExternalFenceHandleTypeFlags>((rand() % 0xFFF) + 1); |
| props.externalFenceFeatures = static_cast<VkExternalFenceFeatureFlags>((rand() % 0xFFF) + 1); |
| } |
| |
| // Compare the external fence data structs |
| static bool CompareExtFenceData(const VkExternalFenceProperties& props1, const VkExternalFenceProperties& props2, |
| bool supported = true) { |
| bool equal = true; |
| if (supported) { |
| equal = equal && props1.externalFenceFeatures == props2.externalFenceFeatures; |
| equal = equal && props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes; |
| equal = equal && props1.compatibleHandleTypes == props2.compatibleHandleTypes; |
| } else { |
| equal = equal && 0 == props2.externalFenceFeatures; |
| equal = equal && 0 == props2.exportFromImportedHandleTypes; |
| equal = equal && 0 == props2.compatibleHandleTypes; |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceExternalFencePropertiesKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalFenceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceExternalFenceProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceExternalFenceInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR}; |
| VkExternalFencePropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR}; |
| GetPhysicalDeviceExternalFenceProperties(physical_device, &info, &props); |
| ASSERT_TRUE(CompareExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties, props)); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalFenceProperties where instance supports, an ICD, and a device under that ICD |
| // also support, so everything should work and return properly. |
| TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2Simple) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; |
| env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0}); |
| FillInRandomExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalFenceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFenceProperties>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalFenceProperties")); |
| ASSERT_NE(GetPhysicalDeviceExternalFenceProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO}; |
| VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES}; |
| GetPhysicalDeviceExternalFenceProperties(physical_device, &info, &props); |
| ASSERT_TRUE(CompareExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties, props)); |
| } |
| |
| // Test vkGetPhysicalDeviceExternalFenceProperties where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); |
| } else { |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomExtFenceData(cur_dev.external_fence_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.set_api_version(VK_API_VERSION_1_1); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceExternalFenceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFenceProperties>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalFenceProperties")); |
| ASSERT_NE(GetPhysicalDeviceExternalFenceProperties, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO}; |
| VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES}; |
| GetPhysicalDeviceExternalFenceProperties(physical_devices[dev], &info, &props); |
| // No driver support for extension or 1.1 for ICD 1, all others support |
| ASSERT_TRUE(CompareExtFenceData(cur_dev.external_fence_properties, props, icd != 1)); |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // |
| // VK_KHR_get_surface_capabilities2 |
| // |
| |
| // Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceSurfaceCapabilities2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceSurfaceCapabilities2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceSurfaceCapabilities2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceSurfaceCapabilities2, nullptr); |
| } |
| |
| // Fill in random but valid data into the surface capability data struct for the current physical device |
| static void FillInRandomSurfaceCapsData(VkSurfaceCapabilitiesKHR& props) { |
| props.minImageCount = (rand() % 0xFFF) + 1; |
| props.maxImageCount = (rand() % 0xFFF) + 1; |
| props.currentExtent.width = (rand() % 0xFFF) + 1; |
| props.currentExtent.height = (rand() % 0xFFF) + 1; |
| props.minImageExtent.width = (rand() % 0xFFF) + 1; |
| props.minImageExtent.height = (rand() % 0xFFF) + 1; |
| props.maxImageExtent.width = (rand() % 0xFFF) + 1; |
| props.maxImageExtent.height = (rand() % 0xFFF) + 1; |
| props.maxImageArrayLayers = (rand() % 0xFFF) + 1; |
| props.supportedTransforms = static_cast<VkSurfaceTransformFlagsKHR>((rand() % 0xFFF) + 1); |
| props.currentTransform = static_cast<VkSurfaceTransformFlagBitsKHR>((rand() % 0xFFF) + 1); |
| props.supportedCompositeAlpha = static_cast<VkCompositeAlphaFlagsKHR>((rand() % 0xFFF) + 1); |
| props.supportedUsageFlags = static_cast<VkImageUsageFlags>((rand() % 0xFFF) + 1); |
| } |
| |
| // Compare the surface capability data structs |
| static bool CompareSurfaceCapsData(const VkSurfaceCapabilitiesKHR& props1, const VkSurfaceCapabilitiesKHR& props2, |
| bool supported = true) { |
| bool equal = true; |
| if (supported) { |
| equal = equal && props1.minImageCount == props2.minImageCount; |
| equal = equal && props1.maxImageCount == props2.maxImageCount; |
| equal = equal && props1.currentExtent.width == props2.currentExtent.width; |
| equal = equal && props1.currentExtent.height == props2.currentExtent.height; |
| equal = equal && props1.minImageExtent.width == props2.minImageExtent.width; |
| equal = equal && props1.minImageExtent.height == props2.minImageExtent.height; |
| equal = equal && props1.maxImageExtent.width == props2.maxImageExtent.width; |
| equal = equal && props1.maxImageExtent.height == props2.maxImageExtent.height; |
| equal = equal && props1.maxImageArrayLayers == props2.maxImageArrayLayers; |
| equal = equal && props1.supportedTransforms == props2.supportedTransforms; |
| equal = equal && props1.currentTransform == props2.currentTransform; |
| equal = equal && props1.supportedCompositeAlpha == props2.supportedCompositeAlpha; |
| equal = equal && props1.supportedUsageFlags == props2.supportedUsageFlags; |
| } else { |
| equal = equal && 0 == props2.minImageCount; |
| equal = equal && 0 == props2.maxImageCount; |
| equal = equal && 0 == props2.currentExtent.width; |
| equal = equal && 0 == props2.currentExtent.height; |
| equal = equal && 0 == props2.minImageExtent.width; |
| equal = equal && 0 == props2.minImageExtent.height; |
| equal = equal && 0 == props2.maxImageExtent.width; |
| equal = equal && 0 == props2.maxImageExtent.height; |
| equal = equal && 0 == props2.maxImageArrayLayers; |
| equal = equal && 0 == props2.supportedTransforms; |
| equal = equal && 0 == props2.currentTransform; |
| equal = equal && 0 == props2.supportedCompositeAlpha; |
| equal = equal && 0 == props2.supportedUsageFlags; |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; |
| Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext, third_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomSurfaceCapsData(env.get_test_icd(0).physical_devices.back().surface_capabilities); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions( |
| {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceSurfaceCapabilities = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceCapabilities, nullptr); |
| auto CreateHeadlessSurfaceEXT = reinterpret_cast<PFN_vkCreateHeadlessSurfaceEXT>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT")); |
| ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); |
| auto DestroySurfaceKHR = |
| reinterpret_cast<PFN_vkDestroySurfaceKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkDestroySurfaceKHR")); |
| ASSERT_NE(DestroySurfaceKHR, nullptr); |
| auto GetPhysicalDeviceSurfaceCapabilities2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceCapabilities2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkSurfaceKHR surface; |
| VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; |
| ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); |
| |
| VkSurfaceCapabilitiesKHR props{}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilities(physical_device, surface, &props)); |
| |
| VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; |
| VkSurfaceCapabilities2KHR props2{VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilities2(physical_device, &info, &props2)); |
| ASSERT_TRUE(CompareSurfaceCapsData(props, props2.surfaceCapabilities)); |
| |
| DestroySurfaceKHR(instance.inst, surface, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceSurfaceCapabilities2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; |
| Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extensions({first_ext, third_ext}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension(second_ext); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_SURFACE_EXTENSION_NAME, 0}); |
| cur_dev.extensions.push_back({VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomSurfaceCapsData(cur_dev.surface_capabilities); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions( |
| {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceSurfaceCapabilities = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceCapabilities, nullptr); |
| auto CreateHeadlessSurfaceEXT = reinterpret_cast<PFN_vkCreateHeadlessSurfaceEXT>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT")); |
| ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); |
| auto DestroySurfaceKHR = |
| reinterpret_cast<PFN_vkDestroySurfaceKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkDestroySurfaceKHR")); |
| ASSERT_NE(DestroySurfaceKHR, nullptr); |
| auto GetPhysicalDeviceSurfaceCapabilities2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceCapabilities2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| VkSurfaceKHR surface; |
| VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; |
| ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkSurfaceCapabilitiesKHR props{}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilities(physical_devices[dev], surface, &props)); |
| |
| VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; |
| VkSurfaceCapabilities2KHR props2{VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR}; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilities2(physical_devices[dev], &info, &props2)); |
| ASSERT_TRUE(CompareSurfaceCapsData(props, props2.surfaceCapabilities)); |
| } |
| |
| DestroySurfaceKHR(instance.inst, surface, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceSurfaceFormats2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceSurfaceFormats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormats2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceSurfaceFormats2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceSurfaceFormats2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceSurfaceFormats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormats2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceSurfaceFormats2, nullptr); |
| } |
| |
| // Fill in random but valid data into the surface formats data struct for the current physical device |
| static void FillInRandomSurfaceFormatsData(std::vector<VkSurfaceFormatKHR>& props) { |
| props.resize((rand() % 5) + 1); |
| for (uint32_t i = 0; i < props.size(); ++i) { |
| props[i].format = static_cast<VkFormat>((rand() % 0xFFF) + 1); |
| props[i].colorSpace = static_cast<VkColorSpaceKHR>((rand() % 0xFFF) + 1); |
| } |
| } |
| |
| // Compare the surface formats data structs |
| static bool CompareSurfaceFormatsData(const std::vector<VkSurfaceFormatKHR>& props1, const std::vector<VkSurfaceFormat2KHR>& props2, |
| bool supported = true) { |
| if (props1.size() != props2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < props1.size(); ++i) { |
| if (supported) { |
| equal = equal && props1[i].format == props2[i].surfaceFormat.format; |
| equal = equal && props1[i].colorSpace == props2[i].surfaceFormat.colorSpace; |
| } else { |
| equal = equal && 0 == props2[i].surfaceFormat.format; |
| equal = equal && 0 == props2[i].surfaceFormat.colorSpace; |
| } |
| } |
| return equal; |
| } |
| |
| // Test vkGetPhysicalDeviceSurfaceFormats2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; |
| Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext, third_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomSurfaceFormatsData(env.get_test_icd(0).physical_devices.back().surface_formats); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions( |
| {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceSurfaceFormats = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceFormats, nullptr); |
| auto CreateHeadlessSurfaceEXT = reinterpret_cast<PFN_vkCreateHeadlessSurfaceEXT>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT")); |
| ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); |
| auto DestroySurfaceKHR = |
| reinterpret_cast<PFN_vkDestroySurfaceKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkDestroySurfaceKHR")); |
| ASSERT_NE(DestroySurfaceKHR, nullptr); |
| auto GetPhysicalDeviceSurfaceFormats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormats2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceFormats2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkSurfaceKHR surface; |
| VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; |
| ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); |
| |
| std::vector<VkSurfaceFormatKHR> props{}; |
| uint32_t count_1 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats(physical_device, surface, &count_1, nullptr)); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().surface_formats.size(), count_1); |
| props.resize(count_1); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats(physical_device, surface, &count_1, props.data())); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().surface_formats.size(), count_1); |
| |
| VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; |
| std::vector<VkSurfaceFormat2KHR> props2{}; |
| uint32_t count_2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2(physical_device, &info, &count_2, nullptr)); |
| ASSERT_EQ(count_1, count_2); |
| props2.resize(count_2, VkSurfaceFormat2KHR{VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2(physical_device, &info, &count_2, props2.data())); |
| ASSERT_TRUE(CompareSurfaceFormatsData(props, props2)); |
| |
| DestroySurfaceKHR(instance.inst, surface, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceSurfaceFormats2 where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; |
| Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extensions({first_ext, third_ext}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension(second_ext); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_SURFACE_EXTENSION_NAME, 0}); |
| cur_dev.extensions.push_back({VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomSurfaceFormatsData(cur_dev.surface_formats); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions( |
| {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceSurfaceFormats = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceFormats, nullptr); |
| auto CreateHeadlessSurfaceEXT = reinterpret_cast<PFN_vkCreateHeadlessSurfaceEXT>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT")); |
| ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); |
| auto DestroySurfaceKHR = |
| reinterpret_cast<PFN_vkDestroySurfaceKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkDestroySurfaceKHR")); |
| ASSERT_NE(DestroySurfaceKHR, nullptr); |
| auto GetPhysicalDeviceSurfaceFormats2 = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormats2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR")); |
| ASSERT_NE(GetPhysicalDeviceSurfaceFormats2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| VkSurfaceKHR surface; |
| VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; |
| ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| std::vector<VkSurfaceFormatKHR> props{}; |
| uint32_t count_1 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats(physical_devices[dev], surface, &count_1, nullptr)); |
| ASSERT_NE(0, count_1); |
| props.resize(count_1); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats(physical_devices[dev], surface, &count_1, props.data())); |
| ASSERT_NE(0, count_1); |
| |
| VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; |
| std::vector<VkSurfaceFormat2KHR> props2{}; |
| uint32_t count_2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2(physical_devices[dev], &info, &count_2, nullptr)); |
| ASSERT_EQ(count_1, count_2); |
| props2.resize(count_2, VkSurfaceFormat2KHR{VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2(physical_devices[dev], &info, &count_2, props2.data())); |
| ASSERT_EQ(count_1, count_2); |
| ASSERT_TRUE(CompareSurfaceFormatsData(props, props2)); |
| } |
| |
| DestroySurfaceKHR(instance.inst, surface, nullptr); |
| } |
| |
| // |
| // VK_KHR_display |
| // |
| |
| // Test vkGetPhysicalDeviceDisplayPropertiesKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayProperties, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPropertiesKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceDisplayProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayProperties, nullptr); |
| } |
| |
| VkDisplayKHR CreateRandomDisplay() { return (VkDisplayKHR)(((rand() % 0xFFFFFFFBull) << 12) * (rand() % 0xFFFFFFFull) + 1); } |
| |
| VkDisplayModeKHR CreateRandomDisplayMode() { |
| return (VkDisplayModeKHR)(((rand() % 0xFFFFFFFBull) << 12) * (rand() % 0xFFFFFFFull) + 1); |
| } |
| |
| // Fill in random but valid data into the display property data struct for the current physical device |
| static void FillInRandomDisplayPropData(std::vector<VkDisplayPropertiesKHR>& props) { |
| props.resize((rand() % 5) + 1); |
| for (uint32_t i = 0; i < props.size(); ++i) { |
| props[i].display = CreateRandomDisplay(); |
| props[i].physicalDimensions.width = static_cast<uint32_t>((rand() % 0xFFF) + 1); |
| props[i].physicalDimensions.height = static_cast<uint32_t>((rand() % 0xFFF) + 1); |
| props[i].physicalResolution.width = static_cast<uint32_t>((rand() % 0xFFF) + 1); |
| props[i].physicalResolution.height = static_cast<uint32_t>((rand() % 0xFFF) + 1); |
| props[i].supportedTransforms = static_cast<VkSurfaceTransformFlagsKHR>((rand() % 0xFFE) + 1); |
| props[i].planeReorderPossible = rand() % 2 > 0 ? VK_TRUE : VK_FALSE; |
| props[i].persistentContent = rand() % 2 > 0 ? VK_TRUE : VK_FALSE; |
| } |
| } |
| |
| // Compare the display property data structs |
| static bool CompareDisplayPropData(const std::vector<VkDisplayPropertiesKHR>& props1, |
| const std::vector<VkDisplayPropertiesKHR>& props2) { |
| if (props1.size() != props2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < props1.size(); ++i) { |
| equal = equal && props1[i].display == props2[i].display; |
| equal = equal && props1[i].physicalDimensions.width == props2[i].physicalDimensions.width; |
| equal = equal && props1[i].physicalDimensions.height == props2[i].physicalDimensions.height; |
| equal = equal && props1[i].physicalResolution.width == props2[i].physicalResolution.width; |
| equal = equal && props1[i].physicalResolution.height == props2[i].physicalResolution.height; |
| equal = equal && props1[i].supportedTransforms == props2[i].supportedTransforms; |
| equal = equal && props1[i].planeReorderPossible == props2[i].planeReorderPossible; |
| equal = equal && props1[i].persistentContent == props2[i].persistentContent; |
| } |
| return equal; |
| } |
| |
| // Test vGetPhysicalDeviceDisplayPropertiesKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkDisplayPropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_device, &prop_count, nullptr)); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_properties.size(), prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_device, &prop_count, props.data())); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_properties.size(), prop_count); |
| |
| ASSERT_TRUE(CompareDisplayPropData(props, env.get_test_icd(0).physical_devices.back().display_properties)); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPropertiesKHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomDisplayPropData(cur_dev.display_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayProperties, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| std::vector<VkDisplayPropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_devices[dev], &prop_count, nullptr)); |
| if (icd == 1) { |
| // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the |
| // loader. |
| ASSERT_EQ(0, prop_count); |
| } else { |
| ASSERT_EQ(cur_dev.display_properties.size(), prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_devices[dev], &prop_count, props.data())); |
| ASSERT_EQ(cur_dev.display_properties.size(), prop_count); |
| |
| ASSERT_TRUE(CompareDisplayPropData(props, cur_dev.display_properties)); |
| } |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayPlaneProperties, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayPlaneProperties, nullptr); |
| } |
| |
| // Fill in random but valid data into the display plane property data struct for the current physical device |
| static void FillInRandomDisplayPlanePropData(std::vector<VkDisplayPlanePropertiesKHR>& props) { |
| props.resize((rand() % 5) + 1); |
| for (uint32_t i = 0; i < props.size(); ++i) { |
| props[i].currentDisplay = CreateRandomDisplay(); |
| props[i].currentStackIndex = static_cast<uint32_t>((rand() % 0xFFF) + (rand() % 0xFFF) + 1); |
| } |
| } |
| |
| // Compare the display plane property data structs |
| static bool CompareDisplayPlanePropData(const std::vector<VkDisplayPlanePropertiesKHR>& props1, |
| const std::vector<VkDisplayPlanePropertiesKHR>& props2) { |
| if (props1.size() != props2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < props1.size(); ++i) { |
| equal = equal && props1[i].currentDisplay == props2[i].currentDisplay; |
| equal = equal && props1[i].currentStackIndex == props2[i].currentStackIndex; |
| } |
| return equal; |
| } |
| |
| // Test vGetPhysicalDeviceDisplayPlanePropertiesKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomDisplayPlanePropData(env.get_test_icd(0).physical_devices.back().display_plane_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkDisplayPlanePropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties(physical_device, &prop_count, nullptr)); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_plane_properties.size(), prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties(physical_device, &prop_count, props.data())); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_plane_properties.size(), prop_count); |
| |
| ASSERT_TRUE(CompareDisplayPlanePropData(props, env.get_test_icd(0).physical_devices.back().display_plane_properties)); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomDisplayPlanePropData(cur_dev.display_plane_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| std::vector<VkDisplayPlanePropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties(physical_devices[dev], &prop_count, nullptr)); |
| if (icd == 1) { |
| // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the |
| // loader. |
| ASSERT_EQ(0, prop_count); |
| } else { |
| ASSERT_EQ(cur_dev.display_plane_properties.size(), prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, |
| GetPhysicalDeviceDisplayPlaneProperties(physical_devices[dev], &prop_count, props.data())); |
| ASSERT_EQ(cur_dev.display_plane_properties.size(), prop_count); |
| |
| ASSERT_TRUE(CompareDisplayPlanePropData(props, cur_dev.display_plane_properties)); |
| } |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // Test vkGetDisplayPlaneSupportedDisplaysKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneSupportedDisplays = reinterpret_cast<PFN_vkGetDisplayPlaneSupportedDisplaysKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR")); |
| ASSERT_EQ(GetDisplayPlaneSupportedDisplays, nullptr); |
| } |
| |
| // Test vkGetDisplayPlaneSupportedDisplaysKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetDisplayPlaneSupportedDisplays = reinterpret_cast<PFN_vkGetDisplayPlaneSupportedDisplaysKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR")); |
| ASSERT_EQ(GetDisplayPlaneSupportedDisplays, nullptr); |
| } |
| |
| // Fill in random but valid data into the display plane property data struct for the current physical device |
| static void GenerateRandomDisplays(std::vector<VkDisplayKHR>& disps) { |
| disps.resize((rand() % 5) + 1); |
| for (uint32_t i = 0; i < disps.size(); ++i) { |
| disps[i] = CreateRandomDisplay(); |
| } |
| } |
| |
| // Compare the display plane property data structs |
| static bool CompareDisplays(const std::vector<VkDisplayKHR>& disps1, const std::vector<VkDisplayKHR>& disps2) { |
| if (disps1.size() != disps2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < disps1.size(); ++i) { |
| equal = equal && disps1[i] == disps2[i]; |
| } |
| return equal; |
| } |
| |
| // Test vGetDisplayPlaneSupportedDisplaysKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneSupportedDisplays = reinterpret_cast<PFN_vkGetDisplayPlaneSupportedDisplaysKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR")); |
| ASSERT_NE(GetDisplayPlaneSupportedDisplays, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkDisplayKHR> disps{}; |
| uint32_t disp_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplays(physical_device, 0, &disp_count, nullptr)); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().displays.size(), disp_count); |
| disps.resize(disp_count); |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplays(physical_device, 0, &disp_count, disps.data())); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().displays.size(), disp_count); |
| |
| ASSERT_TRUE(CompareDisplays(disps, env.get_test_icd(0).physical_devices.back().displays)); |
| } |
| |
| // Test vkGetDisplayPlaneSupportedDisplaysKHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| GenerateRandomDisplays(cur_dev.displays); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneSupportedDisplays = reinterpret_cast<PFN_vkGetDisplayPlaneSupportedDisplaysKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR")); |
| ASSERT_NE(GetDisplayPlaneSupportedDisplays, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| std::vector<VkDisplayKHR> disps{}; |
| uint32_t disp_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplays(physical_devices[dev], 0, &disp_count, nullptr)); |
| if (icd == 1) { |
| // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the |
| // loader. |
| ASSERT_EQ(0, disp_count); |
| } else { |
| ASSERT_EQ(cur_dev.displays.size(), disp_count); |
| disps.resize(disp_count); |
| ASSERT_EQ(VK_SUCCESS, |
| GetDisplayPlaneSupportedDisplays(physical_devices[dev], 0, &disp_count, disps.data())); |
| ASSERT_EQ(cur_dev.displays.size(), disp_count); |
| |
| ASSERT_TRUE(CompareDisplays(disps, cur_dev.displays)); |
| } |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // Test vkGetDisplayModePropertiesKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, GetDispModePropsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetDisplayModeProperties = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModePropertiesKHR")); |
| ASSERT_EQ(GetDisplayModeProperties, nullptr); |
| } |
| |
| // Test vkGetDisplayModePropertiesKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, GetDispModePropsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetDisplayModeProperties = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModePropertiesKHR")); |
| ASSERT_EQ(GetDisplayModeProperties, nullptr); |
| } |
| |
| // Fill in random but valid data into the display mode properties data struct for the current physical device |
| static void GenerateRandomDisplayModeProps(std::vector<VkDisplayModePropertiesKHR>& disps) { |
| disps.resize((rand() % 5) + 1); |
| for (uint32_t i = 0; i < disps.size(); ++i) { |
| disps[i].displayMode = CreateRandomDisplayMode(); |
| disps[i].parameters.visibleRegion.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| disps[i].parameters.visibleRegion.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| disps[i].parameters.refreshRate = 1 << (rand() % 8); |
| } |
| } |
| |
| // Compare the display mode properties data structs |
| static bool CompareDisplayModeProps(const std::vector<VkDisplayModePropertiesKHR>& disps1, |
| const std::vector<VkDisplayModePropertiesKHR>& disps2) { |
| if (disps1.size() != disps2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < disps1.size(); ++i) { |
| equal = equal && disps1[i].displayMode == disps2[i].displayMode; |
| equal = equal && disps1[i].parameters.visibleRegion.width == disps2[i].parameters.visibleRegion.width; |
| equal = equal && disps1[i].parameters.visibleRegion.height == disps2[i].parameters.visibleRegion.height; |
| equal = equal && disps1[i].parameters.refreshRate == disps2[i].parameters.refreshRate; |
| } |
| return equal; |
| } |
| |
| // Test vGetDisplayModePropertiesKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, GetDispModePropsKHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| GenerateRandomDisplayModeProps(env.get_test_icd(0).physical_devices.back().display_mode_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDisplayModeProperties = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModePropertiesKHR")); |
| ASSERT_NE(GetDisplayModeProperties, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkDisplayModePropertiesKHR> props{}; |
| uint32_t props_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties(physical_device, VK_NULL_HANDLE, &props_count, nullptr)); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_mode_properties.size(), props_count); |
| props.resize(props_count); |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties(physical_device, VK_NULL_HANDLE, &props_count, props.data())); |
| ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_mode_properties.size(), props_count); |
| |
| ASSERT_TRUE(CompareDisplayModeProps(props, env.get_test_icd(0).physical_devices.back().display_mode_properties)); |
| } |
| |
| // Test vkGetDisplayModePropertiesKHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, GetDispModePropsKHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| GenerateRandomDisplayModeProps(cur_dev.display_mode_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetDisplayModeProperties = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModePropertiesKHR")); |
| ASSERT_NE(GetDisplayModeProperties, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| uint32_t props_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties(physical_devices[dev], VK_NULL_HANDLE, &props_count, nullptr)); |
| if (icd == 1) { |
| // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the |
| // loader. |
| ASSERT_EQ(0, props_count); |
| } else { |
| std::vector<VkDisplayModePropertiesKHR> props{}; |
| ASSERT_EQ(cur_dev.display_mode_properties.size(), props_count); |
| props.resize(props_count); |
| ASSERT_EQ(VK_SUCCESS, |
| GetDisplayModeProperties(physical_devices[dev], VK_NULL_HANDLE, &props_count, props.data())); |
| ASSERT_EQ(cur_dev.display_mode_properties.size(), props_count); |
| |
| ASSERT_TRUE(CompareDisplayModeProps(props, cur_dev.display_mode_properties)); |
| } |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // Test vkCreateDisplayModeKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, GetDispModesKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto CreateDisplayMode = |
| reinterpret_cast<PFN_vkCreateDisplayModeKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkCreateDisplayModeKHR")); |
| ASSERT_EQ(CreateDisplayMode, nullptr); |
| } |
| |
| // Test vkCreateDisplayModeKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, GetDispModesKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto CreateDisplayMode = |
| reinterpret_cast<PFN_vkCreateDisplayModeKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkCreateDisplayModeKHR")); |
| ASSERT_EQ(CreateDisplayMode, nullptr); |
| } |
| |
| // Compare the display modes |
| static bool CompareDisplayModes(const VkDisplayModeKHR& disps1, VkDisplayModeKHR& disps2) { return disps1 == disps2; } |
| |
| // Test vkCreateDisplayModeKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, GetDispModesKHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| env.get_test_icd(0).physical_devices.back().display_mode = CreateRandomDisplayMode(); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto CreateDisplayMode = |
| reinterpret_cast<PFN_vkCreateDisplayModeKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkCreateDisplayModeKHR")); |
| ASSERT_NE(CreateDisplayMode, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkDisplayModeKHR mode{}; |
| VkDisplayModeCreateInfoKHR create_info{VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR}; |
| ASSERT_EQ(VK_SUCCESS, CreateDisplayMode(physical_device, VK_NULL_HANDLE, &create_info, nullptr, &mode)); |
| ASSERT_TRUE(CompareDisplayModes(mode, env.get_test_icd(0).physical_devices.back().display_mode)); |
| } |
| |
| // Test vkCreateDisplayModeKHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, GetDispModesKHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| cur_dev.display_mode = CreateRandomDisplayMode(); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto CreateDisplayMode = |
| reinterpret_cast<PFN_vkCreateDisplayModeKHR>(instance.functions->vkGetInstanceProcAddr(instance, "vkCreateDisplayModeKHR")); |
| ASSERT_NE(CreateDisplayMode, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| VkDisplayModeKHR mode{}; |
| VkDisplayModeCreateInfoKHR create_info{VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR}; |
| if (icd == 1) { |
| // Unsupported ICD should return initialization failed (instead of crash) |
| ASSERT_EQ(VK_ERROR_INITIALIZATION_FAILED, |
| CreateDisplayMode(physical_devices[dev], VK_NULL_HANDLE, &create_info, nullptr, &mode)); |
| } else { |
| ASSERT_EQ(VK_SUCCESS, |
| CreateDisplayMode(physical_devices[dev], VK_NULL_HANDLE, &create_info, nullptr, &mode)); |
| ASSERT_TRUE(CompareDisplayModes(mode, cur_dev.display_mode)); |
| } |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // Test vkGetDisplayPlaneCapabilitiesKHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_EQ(GetDisplayPlaneCapabilities, nullptr); |
| } |
| |
| // Test vkGetDisplayPlaneCapabilitiesKHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_EQ(GetDisplayPlaneCapabilities, nullptr); |
| } |
| |
| // Fill in random but valid data into the display plane caps for the current physical device |
| static void GenerateRandomDisplayPlaneCaps(VkDisplayPlaneCapabilitiesKHR& caps) { |
| caps.supportedAlpha = static_cast<VkDisplayPlaneAlphaFlagsKHR>((rand() % 0xFFFFFFF) + 1); |
| caps.minSrcPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.minSrcPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxSrcPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxSrcPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.minSrcExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.minSrcExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxSrcExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxSrcExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.minDstPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.minDstPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxDstPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxDstPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.minDstExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.minDstExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxDstExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| caps.maxDstExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); |
| } |
| |
| // Compare the display plane caps |
| static bool CompareDisplayPlaneCaps(const VkDisplayPlaneCapabilitiesKHR& caps1, VkDisplayPlaneCapabilitiesKHR& caps2, |
| bool supported = true) { |
| bool equal = true; |
| if (supported) { |
| equal = equal && caps1.supportedAlpha == caps2.supportedAlpha; |
| equal = equal && caps1.minSrcPosition.x == caps2.minSrcPosition.x; |
| equal = equal && caps1.minSrcPosition.y == caps2.minSrcPosition.y; |
| equal = equal && caps1.maxSrcPosition.x == caps2.maxSrcPosition.x; |
| equal = equal && caps1.maxSrcPosition.y == caps2.maxSrcPosition.y; |
| equal = equal && caps1.minSrcExtent.width == caps2.minSrcExtent.width; |
| equal = equal && caps1.minSrcExtent.height == caps2.minSrcExtent.height; |
| equal = equal && caps1.maxSrcExtent.width == caps2.maxSrcExtent.width; |
| equal = equal && caps1.maxSrcExtent.height == caps2.maxSrcExtent.height; |
| equal = equal && caps1.minDstPosition.x == caps2.minDstPosition.x; |
| equal = equal && caps1.minDstPosition.y == caps2.minDstPosition.y; |
| equal = equal && caps1.maxDstPosition.x == caps2.maxDstPosition.x; |
| equal = equal && caps1.maxDstPosition.y == caps2.maxDstPosition.y; |
| equal = equal && caps1.minDstExtent.width == caps2.minDstExtent.width; |
| equal = equal && caps1.minDstExtent.height == caps2.minDstExtent.height; |
| equal = equal && caps1.maxDstExtent.width == caps2.maxDstExtent.width; |
| equal = equal && caps1.maxDstExtent.height == caps2.maxDstExtent.height; |
| } else { |
| equal = equal && caps1.supportedAlpha == 0; |
| equal = equal && caps1.minSrcPosition.x == 0; |
| equal = equal && caps1.minSrcPosition.y == 0; |
| equal = equal && caps1.maxSrcPosition.x == 0; |
| equal = equal && caps1.maxSrcPosition.y == 0; |
| equal = equal && caps1.minSrcExtent.width == 0; |
| equal = equal && caps1.minSrcExtent.height == 0; |
| equal = equal && caps1.maxSrcExtent.width == 0; |
| equal = equal && caps1.maxSrcExtent.height == 0; |
| equal = equal && caps1.minDstPosition.x == 0; |
| equal = equal && caps1.minDstPosition.y == 0; |
| equal = equal && caps1.maxDstPosition.x == 0; |
| equal = equal && caps1.maxDstPosition.y == 0; |
| equal = equal && caps1.minDstExtent.width == 0; |
| equal = equal && caps1.minDstExtent.height == 0; |
| equal = equal && caps1.maxDstExtent.width == 0; |
| equal = equal && caps1.maxDstExtent.height == 0; |
| } |
| return equal; |
| } |
| |
| // Test vkGetDisplayPlaneCapabilitiesKHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| GenerateRandomDisplayPlaneCaps(env.get_test_icd(0).physical_devices.back().display_plane_capabilities); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_NE(GetDisplayPlaneCapabilities, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkDisplayPlaneCapabilitiesKHR caps{}; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities(physical_device, 0, 0, &caps)); |
| ASSERT_TRUE(CompareDisplayPlaneCaps(caps, env.get_test_icd(0).physical_devices.back().display_plane_capabilities)); |
| } |
| |
| // Test vkGetDisplayPlaneCapabilitiesKHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| GenerateRandomDisplayPlaneCaps(cur_dev.display_plane_capabilities); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_NE(GetDisplayPlaneCapabilities, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| VkDisplayPlaneCapabilitiesKHR caps{}; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities(physical_devices[dev], 0, 0, &caps)); |
| ASSERT_TRUE(CompareDisplayPlaneCaps(caps, cur_dev.display_plane_capabilities, icd != 1)); |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // |
| // VK_KHR_get_display_properties2 |
| // |
| |
| // Test vkGetPhysicalDeviceDisplayProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayProperties2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayProperties2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceDisplayProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayProperties2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayProperties2, nullptr); |
| } |
| |
| // Compare the display property data structs |
| static bool CompareDisplayPropData(const std::vector<VkDisplayPropertiesKHR>& props1, |
| const std::vector<VkDisplayProperties2KHR>& props2) { |
| if (props1.size() != props2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < props1.size(); ++i) { |
| equal = equal && props1[i].display == props2[i].displayProperties.display; |
| equal = equal && props1[i].physicalDimensions.width == props2[i].displayProperties.physicalDimensions.width; |
| equal = equal && props1[i].physicalDimensions.height == props2[i].displayProperties.physicalDimensions.height; |
| equal = equal && props1[i].physicalResolution.width == props2[i].displayProperties.physicalResolution.width; |
| equal = equal && props1[i].physicalResolution.height == props2[i].displayProperties.physicalResolution.height; |
| equal = equal && props1[i].supportedTransforms == props2[i].displayProperties.supportedTransforms; |
| equal = equal && props1[i].planeReorderPossible == props2[i].displayProperties.planeReorderPossible; |
| equal = equal && props1[i].persistentContent == props2[i].displayProperties.persistentContent; |
| } |
| return equal; |
| } |
| |
| // Test vGetPhysicalDeviceDisplayProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayProperties, nullptr); |
| auto GetPhysicalDeviceDisplayProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayProperties2KHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayProperties2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkDisplayPropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_device, &prop_count, nullptr)); |
| ASSERT_NE(0, prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_device, &prop_count, props.data())); |
| |
| std::vector<VkDisplayProperties2KHR> props2{}; |
| uint32_t prop_count_2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2(physical_device, &prop_count_2, nullptr)); |
| ASSERT_EQ(prop_count, prop_count_2); |
| props2.resize(prop_count_2, {VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2(physical_device, &prop_count_2, props2.data())); |
| ASSERT_EQ(prop_count, prop_count_2); |
| |
| ASSERT_TRUE(CompareDisplayPropData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayProperties2KHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomDisplayPropData(cur_dev.display_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayProperties, nullptr); |
| auto GetPhysicalDeviceDisplayProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayProperties2KHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayProperties2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| std::vector<VkDisplayPropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_devices[dev], &prop_count, nullptr)); |
| ASSERT_NE(0, prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties(physical_devices[dev], &prop_count, props.data())); |
| |
| std::vector<VkDisplayProperties2KHR> props2{}; |
| uint32_t prop_count_2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2(physical_devices[dev], &prop_count_2, nullptr)); |
| ASSERT_EQ(prop_count, prop_count_2); |
| props2.resize(prop_count_2, {VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2(physical_devices[dev], &prop_count_2, props2.data())); |
| ASSERT_EQ(prop_count, prop_count_2); |
| |
| ASSERT_TRUE(CompareDisplayPropData(props, props2)); |
| } |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayPlaneProperties2, nullptr); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")); |
| ASSERT_EQ(GetPhysicalDeviceDisplayPlaneProperties2, nullptr); |
| } |
| |
| // Compare the display plane property data structs |
| static bool CompareDisplayPlanePropData(const std::vector<VkDisplayPlanePropertiesKHR>& props1, |
| const std::vector<VkDisplayPlaneProperties2KHR>& props2) { |
| if (props1.size() != props2.size()) return false; |
| bool equal = true; |
| for (uint32_t i = 0; i < props1.size(); ++i) { |
| equal = equal && props1[i].currentDisplay == props2[i].displayPlaneProperties.currentDisplay; |
| equal = equal && props1[i].currentStackIndex == props2[i].displayPlaneProperties.currentStackIndex; |
| } |
| return equal; |
| } |
| |
| // Test vGetPhysicalDeviceDisplayPlaneProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomDisplayPlanePropData(env.get_test_icd(0).physical_devices.back().display_plane_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties, nullptr); |
| auto GetPhysicalDeviceDisplayPlaneProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkDisplayPlanePropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties(physical_device, &prop_count, nullptr)); |
| ASSERT_NE(0, prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties(physical_device, &prop_count, props.data())); |
| |
| std::vector<VkDisplayPlaneProperties2KHR> props2{}; |
| uint32_t prop_count2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2(physical_device, &prop_count2, nullptr)); |
| ASSERT_EQ(prop_count, prop_count2); |
| props2.resize(prop_count2, {VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2(physical_device, &prop_count2, props2.data())); |
| |
| ASSERT_TRUE(CompareDisplayPlanePropData(props, props2)); |
| } |
| |
| // Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| FillInRandomDisplayPlanePropData(cur_dev.display_plane_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetPhysicalDeviceDisplayPlaneProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties, nullptr); |
| auto GetPhysicalDeviceDisplayPlaneProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")); |
| ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| std::vector<VkDisplayPlanePropertiesKHR> props{}; |
| uint32_t prop_count = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties(physical_devices[dev], &prop_count, nullptr)); |
| ASSERT_NE(0, prop_count); |
| props.resize(prop_count); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties(physical_devices[dev], &prop_count, props.data())); |
| |
| std::vector<VkDisplayPlaneProperties2KHR> props2{}; |
| uint32_t prop_count2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2(physical_devices[dev], &prop_count2, nullptr)); |
| ASSERT_EQ(prop_count, prop_count2); |
| props2.resize(prop_count2, {VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2(physical_devices[dev], &prop_count2, props2.data())); |
| |
| ASSERT_TRUE(CompareDisplayPlanePropData(props, props2)); |
| } |
| } |
| |
| // Test vkGetDisplayModeProperties2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetDisplayModeProperties2 = reinterpret_cast<PFN_vkGetDisplayModeProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModeProperties2KHR")); |
| ASSERT_EQ(GetDisplayModeProperties2, nullptr); |
| } |
| |
| // Test vkGetDisplayModeProperties2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetDisplayModeProperties2 = reinterpret_cast<PFN_vkGetDisplayModeProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModeProperties2KHR")); |
| ASSERT_EQ(GetDisplayModeProperties2, nullptr); |
| } |
| |
| // Compare the display mode properties data structs |
| static bool CompareDisplayModeProps(const std::vector<VkDisplayModePropertiesKHR>& disps1, |
| const std::vector<VkDisplayModeProperties2KHR>& disps2) { |
| if (disps1.size() != disps2.size()) return false; |
| |
| bool equal = true; |
| for (uint32_t i = 0; i < disps1.size(); ++i) { |
| equal = equal && disps1[i].displayMode == disps2[i].displayModeProperties.displayMode; |
| equal = equal && disps1[i].parameters.visibleRegion.width == disps2[i].displayModeProperties.parameters.visibleRegion.width; |
| equal = |
| equal && disps1[i].parameters.visibleRegion.height == disps2[i].displayModeProperties.parameters.visibleRegion.height; |
| equal = equal && disps1[i].parameters.refreshRate == disps2[i].displayModeProperties.parameters.refreshRate; |
| } |
| return equal; |
| } |
| |
| // Test vGetDisplayModeProperties2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| GenerateRandomDisplayModeProps(env.get_test_icd(0).physical_devices.back().display_mode_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDisplayModeProperties = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModePropertiesKHR")); |
| ASSERT_NE(GetDisplayModeProperties, nullptr); |
| auto GetDisplayModeProperties2 = reinterpret_cast<PFN_vkGetDisplayModeProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModeProperties2KHR")); |
| ASSERT_NE(GetDisplayModeProperties2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| std::vector<VkDisplayModePropertiesKHR> props{}; |
| uint32_t props_count1 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties(physical_device, VK_NULL_HANDLE, &props_count1, nullptr)); |
| ASSERT_NE(0, props_count1); |
| props.resize(props_count1); |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties(physical_device, VK_NULL_HANDLE, &props_count1, props.data())); |
| |
| std::vector<VkDisplayModeProperties2KHR> props2{}; |
| uint32_t props_count2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2(physical_device, VK_NULL_HANDLE, &props_count2, nullptr)); |
| ASSERT_EQ(props_count1, props_count2); |
| props2.resize(props_count2, {VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2(physical_device, VK_NULL_HANDLE, &props_count2, props2.data())); |
| |
| ASSERT_TRUE(CompareDisplayModeProps(props, props2)); |
| } |
| |
| // Test vkGetDisplayModeProperties2KHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| GenerateRandomDisplayModeProps(cur_dev.display_mode_properties); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDisplayModeProperties = reinterpret_cast<PFN_vkGetDisplayModePropertiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModePropertiesKHR")); |
| ASSERT_NE(GetDisplayModeProperties, nullptr); |
| auto GetDisplayModeProperties2 = reinterpret_cast<PFN_vkGetDisplayModeProperties2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayModeProperties2KHR")); |
| ASSERT_NE(GetDisplayModeProperties2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| std::vector<VkDisplayModePropertiesKHR> props{}; |
| uint32_t props_count1 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties(physical_devices[dev], VK_NULL_HANDLE, &props_count1, nullptr)); |
| ASSERT_NE(0, props_count1); |
| props.resize(props_count1); |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties(physical_devices[dev], VK_NULL_HANDLE, &props_count1, props.data())); |
| |
| std::vector<VkDisplayModeProperties2KHR> props2{}; |
| uint32_t props_count2 = 0; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2(physical_devices[dev], VK_NULL_HANDLE, &props_count2, nullptr)); |
| ASSERT_EQ(props_count1, props_count2); |
| props2.resize(props_count2, {VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR}); |
| ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2(physical_devices[dev], VK_NULL_HANDLE, &props_count2, props2.data())); |
| |
| ASSERT_TRUE(CompareDisplayModeProps(props, props2)); |
| } |
| } |
| |
| // Test vkGetDisplayPlaneCapabilities2KHR where nothing supports it. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_EQ(GetDisplayPlaneCapabilities, nullptr); |
| } |
| |
| // Test vkGetDisplayPlaneCapabilities2KHR where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_EQ(GetDisplayPlaneCapabilities, nullptr); |
| } |
| |
| // Compare the display plane caps |
| static bool CompareDisplayPlaneCaps(const VkDisplayPlaneCapabilitiesKHR& caps1, VkDisplayPlaneCapabilities2KHR& caps2) { |
| bool equal = true; |
| equal = equal && caps1.supportedAlpha == caps2.capabilities.supportedAlpha; |
| equal = equal && caps1.minSrcPosition.x == caps2.capabilities.minSrcPosition.x; |
| equal = equal && caps1.minSrcPosition.y == caps2.capabilities.minSrcPosition.y; |
| equal = equal && caps1.maxSrcPosition.x == caps2.capabilities.maxSrcPosition.x; |
| equal = equal && caps1.maxSrcPosition.y == caps2.capabilities.maxSrcPosition.y; |
| equal = equal && caps1.minSrcExtent.width == caps2.capabilities.minSrcExtent.width; |
| equal = equal && caps1.minSrcExtent.height == caps2.capabilities.minSrcExtent.height; |
| equal = equal && caps1.maxSrcExtent.width == caps2.capabilities.maxSrcExtent.width; |
| equal = equal && caps1.maxSrcExtent.height == caps2.capabilities.maxSrcExtent.height; |
| equal = equal && caps1.minDstPosition.x == caps2.capabilities.minDstPosition.x; |
| equal = equal && caps1.minDstPosition.y == caps2.capabilities.minDstPosition.y; |
| equal = equal && caps1.maxDstPosition.x == caps2.capabilities.maxDstPosition.x; |
| equal = equal && caps1.maxDstPosition.y == caps2.capabilities.maxDstPosition.y; |
| equal = equal && caps1.minDstExtent.width == caps2.capabilities.minDstExtent.width; |
| equal = equal && caps1.minDstExtent.height == caps2.capabilities.minDstExtent.height; |
| equal = equal && caps1.maxDstExtent.width == caps2.capabilities.maxDstExtent.width; |
| equal = equal && caps1.maxDstExtent.height == caps2.capabilities.maxDstExtent.height; |
| return equal; |
| } |
| |
| // Test vkGetDisplayPlaneCapabilities2KHR where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; |
| Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_NE(GetDisplayPlaneCapabilities, nullptr); |
| auto GetDisplayPlaneCapabilities2 = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilities2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilities2KHR")); |
| ASSERT_NE(GetDisplayPlaneCapabilities2, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkDisplayPlaneCapabilitiesKHR caps{}; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities(physical_device, 0, 0, &caps)); |
| VkDisplayPlaneCapabilities2KHR caps2{}; |
| VkDisplayPlaneInfo2KHR info{VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR}; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities2(physical_device, &info, &caps2)); |
| ASSERT_TRUE(CompareDisplayPlaneCaps(caps, caps2)); |
| } |
| |
| // Test vkGetDisplayPlaneCapabilities2KHR where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| GenerateRandomDisplayPlaneCaps(cur_dev.display_plane_capabilities); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDisplayPlaneCapabilities = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilitiesKHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")); |
| ASSERT_NE(GetDisplayPlaneCapabilities, nullptr); |
| auto GetDisplayPlaneCapabilities2 = reinterpret_cast<PFN_vkGetDisplayPlaneCapabilities2KHR>( |
| instance.functions->vkGetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilities2KHR")); |
| ASSERT_NE(GetDisplayPlaneCapabilities2, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkDisplayPlaneCapabilitiesKHR caps{}; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities(physical_devices[dev], 0, 0, &caps)); |
| VkDisplayPlaneCapabilities2KHR caps2{}; |
| VkDisplayPlaneInfo2KHR info{VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR}; |
| ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities2(physical_devices[dev], &info, &caps2)); |
| CompareDisplayPlaneCaps(caps, caps2); |
| } |
| } |
| |
| // |
| // VK_EXT_acquire_drm_display |
| // |
| |
| // Test vkAcquireDrmDisplayEXT where nothing supports it. |
| TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto AcquireDrmDisplay = |
| reinterpret_cast<PFN_vkAcquireDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkAcquireDrmDisplayEXT")); |
| ASSERT_EQ(AcquireDrmDisplay, nullptr); |
| } |
| |
| // Test vkAcquireDrmDisplayEXT where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto AcquireDrmDisplay = |
| reinterpret_cast<PFN_vkAcquireDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkAcquireDrmDisplayEXT")); |
| ASSERT_EQ(AcquireDrmDisplay, nullptr); |
| } |
| |
| // Test vkAcquireDrmDisplayEXT where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; |
| Extension second_ext{VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto AcquireDrmDisplay = |
| reinterpret_cast<PFN_vkAcquireDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkAcquireDrmDisplayEXT")); |
| ASSERT_NE(AcquireDrmDisplay, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkDisplayKHR display = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, AcquireDrmDisplay(physical_device, 0, display)); |
| } |
| |
| // Test vkAcquireDrmDisplayEXT where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| GenerateRandomDisplays(cur_dev.displays); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto AcquireDrmDisplay = |
| reinterpret_cast<PFN_vkAcquireDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkAcquireDrmDisplayEXT")); |
| ASSERT_NE(AcquireDrmDisplay, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| VkDisplayKHR display = VK_NULL_HANDLE; |
| if (icd == 1) { |
| // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the |
| // loader. |
| ASSERT_EQ(VK_ERROR_INITIALIZATION_FAILED, AcquireDrmDisplay(physical_devices[dev], 0, display)); |
| } else { |
| ASSERT_EQ(VK_SUCCESS, AcquireDrmDisplay(physical_devices[dev], 0, display)); |
| } |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| // Test vkGetDrmDisplayEXT where nothing supports it. |
| TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTNoSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.CheckCreate(); |
| |
| auto GetDrmDisplay = |
| reinterpret_cast<PFN_vkGetDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkGetDrmDisplayEXT")); |
| ASSERT_EQ(GetDrmDisplay, nullptr); |
| } |
| |
| // Test vkGetDrmDisplayEXT where instance supports it, but nothing else. |
| TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTNoICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME); |
| instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); |
| |
| auto GetDrmDisplay = |
| reinterpret_cast<PFN_vkGetDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkGetDrmDisplayEXT")); |
| ASSERT_EQ(GetDrmDisplay, nullptr); |
| } |
| |
| // Test vkGetDrmDisplayEXT where instance and ICD supports it, but device does not support it. |
| TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTInstanceAndICDSupport) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; |
| Extension second_ext{VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}; |
| env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); |
| env.get_test_icd(0).physical_devices.push_back({}); |
| GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays); |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDrmDisplay = |
| reinterpret_cast<PFN_vkGetDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkGetDrmDisplayEXT")); |
| ASSERT_NE(GetDrmDisplay, nullptr); |
| |
| uint32_t driver_count = 1; |
| VkPhysicalDevice physical_device; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); |
| ASSERT_EQ(driver_count, 1); |
| |
| VkDisplayKHR display = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, GetDrmDisplay(physical_device, 0, 0, &display)); |
| ASSERT_EQ(display, env.get_test_icd(0).physical_devices.back().displays[0]); |
| } |
| |
| // Test vkGetDrmDisplayEXT where instance supports it with some ICDs that both support |
| // and don't support it: |
| // ICD 0 supports |
| // Physical device 0 does not |
| // Physical device 1 does |
| // Physical device 2 does not |
| // ICD 1 doesn't support |
| // Physical device 3 does not |
| // ICD 2 supports |
| // Physical device 4 does not |
| // Physical device 5 does not |
| // ICD 3 supports |
| // Physical device 6 does |
| TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTMixed) { |
| FrameworkEnvironment env{}; |
| const uint32_t max_icd_count = 4; |
| const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; |
| const uint32_t max_phys_devs = 7; |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6)); |
| auto& cur_icd = env.get_test_icd(icd); |
| cur_icd.icd_api_version = VK_API_VERSION_1_0; |
| cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); |
| |
| // ICD 1 should not have 1.1 |
| if (icd != 1) { |
| cur_icd.icd_api_version = VK_API_VERSION_1_1; |
| cur_icd.add_instance_extension({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); |
| } |
| |
| uint32_t rand_vendor_id; |
| uint32_t rand_driver_vers; |
| FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); |
| |
| for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { |
| uint32_t device_version = VK_API_VERSION_1_0; |
| cur_icd.physical_devices.push_back({}); |
| auto& cur_dev = cur_icd.physical_devices.back(); |
| cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); |
| |
| // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 |
| if ((icd == 0 && dev == 1) || icd == 3) { |
| cur_dev.extensions.push_back({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME, 0}); |
| device_version = VK_API_VERSION_1_1; |
| } |
| |
| // Still set physical device properties (so we can determine if device is correct API version) |
| FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); |
| GenerateRandomDisplays(cur_dev.displays); |
| } |
| } |
| |
| InstWrapper instance(env.vulkan_functions); |
| instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); |
| instance.CheckCreate(); |
| |
| auto GetDrmDisplay = |
| reinterpret_cast<PFN_vkGetDrmDisplayEXT>(instance.functions->vkGetInstanceProcAddr(instance, "vkGetDrmDisplayEXT")); |
| ASSERT_NE(GetDrmDisplay, nullptr); |
| |
| uint32_t device_count = max_phys_devs; |
| std::array<VkPhysicalDevice, max_phys_devs> physical_devices; |
| ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); |
| ASSERT_EQ(device_count, max_phys_devs); |
| |
| for (uint32_t dev = 0; dev < device_count; ++dev) { |
| VkPhysicalDeviceProperties pd_props{}; |
| instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); |
| |
| for (uint32_t icd = 0; icd < max_icd_count; ++icd) { |
| auto& cur_icd = env.get_test_icd(icd); |
| bool found = false; |
| for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { |
| auto& cur_dev = cur_icd.physical_devices[pd]; |
| // Find the ICD device matching the physical device we're looking at info for so we can compare the |
| // physical devices info with the returned info. |
| if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && |
| cur_dev.properties.deviceType == pd_props.deviceType && |
| cur_dev.properties.driverVersion == pd_props.driverVersion && |
| cur_dev.properties.vendorID == pd_props.vendorID) { |
| VkDisplayKHR display = VK_NULL_HANDLE; |
| if (icd == 1) { |
| // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the |
| // loader. |
| ASSERT_EQ(VK_ERROR_INITIALIZATION_FAILED, GetDrmDisplay(physical_devices[dev], 0, 0, &display)); |
| } else { |
| ASSERT_EQ(VK_SUCCESS, GetDrmDisplay(physical_devices[dev], 0, 0, &display)); |
| ASSERT_EQ(display, cur_dev.displays[0]); |
| } |
| found = true; |
| break; |
| } |
| } |
| if (found) { |
| break; |
| } |
| } |
| } |
| } |
| |
| TEST(LoaderInstPhysDevExts, DifferentInstanceExtensions) { |
| FrameworkEnvironment env{}; |
| |
| // Add 3 drivers each of which supports a different instance extension |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); |
| env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(0).physical_devices.push_back({"pd0", 7}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0}); |
| |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); |
| env.get_test_icd(1).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(1).physical_devices.push_back({"pd1", 0}); |
| env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0}); |
| |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); |
| env.get_test_icd(2).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); |
| env.get_test_icd(2).physical_devices.push_back({"pd2", 1}); |
| env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0}); |
| |
| DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; |
| InstWrapper inst{env.vulkan_functions}; |
| inst.create_info.add_extensions({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, |
| VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, |
| VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); |
| FillDebugUtilsCreateDetails(inst.create_info, log); |
| inst.CheckCreate(); |
| |
| const uint32_t expected_device_count = 3; |
| auto physical_devices = inst.GetPhysDevs(expected_device_count); |
| |
| auto GetPhysicalDeviceExternalBufferProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceExternalBufferPropertiesKHR")); |
| auto GetPhysicalDeviceExternalSemaphoreProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")); |
| auto GetPhysicalDeviceExternalFenceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceExternalFencePropertiesKHR")); |
| ASSERT_NE(nullptr, GetPhysicalDeviceExternalBufferProperties); |
| ASSERT_NE(nullptr, GetPhysicalDeviceExternalSemaphoreProperties); |
| ASSERT_NE(nullptr, GetPhysicalDeviceExternalFenceProperties); |
| |
| // The above are instance extensions, so shouldn't crash even if only one physical device supports each |
| // extension. |
| for (uint32_t dev = 0; dev < expected_device_count; ++dev) { |
| VkPhysicalDeviceExternalBufferInfo ext_buf_info{}; |
| VkExternalBufferProperties ext_buf_props{}; |
| VkPhysicalDeviceExternalSemaphoreInfo ext_sem_info{}; |
| VkExternalSemaphoreProperties ext_sem_props{}; |
| VkPhysicalDeviceExternalFenceInfo ext_fence_info{}; |
| VkExternalFenceProperties ext_fence_props{}; |
| GetPhysicalDeviceExternalBufferProperties(physical_devices[dev], &ext_buf_info, &ext_buf_props); |
| GetPhysicalDeviceExternalSemaphoreProperties(physical_devices[dev], &ext_sem_info, &ext_sem_props); |
| GetPhysicalDeviceExternalFenceProperties(physical_devices[dev], &ext_fence_info, &ext_fence_props); |
| } |
| } |
| |
| TEST(LoaderInstPhysDevExts, DifferentPhysicalDeviceExtensions) { |
| FrameworkEnvironment env{}; |
| |
| // Add 3 drivers each of which supports a different physical device extension |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); |
| env.get_test_icd(0).physical_devices.push_back({"pd0", 7}); |
| env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, 0}); |
| |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); |
| env.get_test_icd(1).physical_devices.push_back({"pd1", 0}); |
| env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, 0}); |
| |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); |
| env.get_test_icd(2).physical_devices.push_back({"pd2", 1}); |
| env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, 0}); |
| |
| DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; |
| InstWrapper inst{env.vulkan_functions}; |
| FillDebugUtilsCreateDetails(inst.create_info, log); |
| inst.CheckCreate(); |
| |
| const uint32_t expected_device_count = 3; |
| auto physical_devices = inst.GetPhysDevs(expected_device_count); |
| |
| auto EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters = |
| reinterpret_cast<PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR")); |
| auto GetPhysicalDeviceMultisampleProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceMultisamplePropertiesEXT")); |
| auto GetPhysicalDeviceCalibrateableTimeDomains = reinterpret_cast<PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT>( |
| inst.functions->vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")); |
| ASSERT_NE(nullptr, EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters); |
| ASSERT_NE(nullptr, GetPhysicalDeviceMultisampleProperties); |
| ASSERT_NE(nullptr, GetPhysicalDeviceCalibrateableTimeDomains); |
| |
| for (uint32_t dev = 0; dev < expected_device_count; ++dev) { |
| uint32_t extension_count = 0; |
| std::vector<VkExtensionProperties> device_extensions; |
| bool supports_query = false; |
| bool supports_samples = false; |
| bool supports_timestamps = false; |
| ASSERT_EQ(VK_SUCCESS, |
| inst->vkEnumerateDeviceExtensionProperties(physical_devices[dev], nullptr, &extension_count, nullptr)); |
| ASSERT_GT(extension_count, 0U); |
| device_extensions.resize(extension_count); |
| ASSERT_EQ(VK_SUCCESS, inst->vkEnumerateDeviceExtensionProperties(physical_devices[dev], nullptr, &extension_count, |
| device_extensions.data())); |
| for (uint32_t ext = 0; ext < extension_count; ++ext) { |
| if (string_eq(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, &device_extensions[ext].extensionName[0])) { |
| supports_query = true; |
| } |
| if (string_eq(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, &device_extensions[ext].extensionName[0])) { |
| supports_samples = true; |
| } |
| if (string_eq(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, &device_extensions[ext].extensionName[0])) { |
| supports_timestamps = true; |
| } |
| } |
| |
| // For physical device extensions, they should work for devices that support it and crash for those that don't. |
| if (supports_query) { |
| ASSERT_EQ(VK_SUCCESS, EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(physical_devices[dev], 0, nullptr, |
| nullptr, nullptr)); |
| } else { |
| ASSERT_DEATH( |
| EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCounters(physical_devices[dev], 0, nullptr, nullptr, nullptr), |
| ""); |
| ASSERT_FALSE( |
| log.find("ICD associated with VkPhysicalDevice does not support " |
| "EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR")); |
| } |
| if (supports_samples) { |
| GetPhysicalDeviceMultisampleProperties(physical_devices[dev], VK_SAMPLE_COUNT_2_BIT, nullptr); |
| } else { |
| ASSERT_DEATH(GetPhysicalDeviceMultisampleProperties(physical_devices[dev], VK_SAMPLE_COUNT_2_BIT, nullptr), ""); |
| ASSERT_FALSE( |
| log.find("ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceMultisamplePropertiesEXT")); |
| } |
| if (supports_timestamps) { |
| ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceCalibrateableTimeDomains(physical_devices[dev], nullptr, nullptr)); |
| } else { |
| ASSERT_DEATH(GetPhysicalDeviceCalibrateableTimeDomains(physical_devices[dev], nullptr, nullptr), ""); |
| ASSERT_FALSE( |
| log.find("ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceCalibrateableTimeDomainsEXT")); |
| } |
| } |
| } |