Flutter Impeller
driver_info_vk_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
9 #include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
11 
12 namespace impeller::testing {
13 
16 
17 TEST_P(DriverInfoVKTest, CanQueryDriverInfo) {
18  ASSERT_TRUE(GetContext());
19  const auto& driver_info =
20  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
21  ASSERT_NE(driver_info, nullptr);
22  // 1.1 is the base Impeller version. The driver can't be lower than that.
23  ASSERT_TRUE(driver_info->GetAPIVersion().IsAtLeast(Version{1, 1, 0}));
24  ASSERT_NE(driver_info->GetVendor(), VendorVK::kUnknown);
25  ASSERT_NE(driver_info->GetDeviceType(), DeviceTypeVK::kUnknown);
26  ASSERT_NE(driver_info->GetDriverName(), "");
27  EXPECT_FALSE(driver_info->IsKnownBadDriver());
28 }
29 
30 TEST_P(DriverInfoVKTest, CanDumpToLog) {
31  ASSERT_TRUE(GetContext());
32  const auto& driver_info =
33  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
34  ASSERT_NE(driver_info, nullptr);
35  fml::testing::LogCapture log;
36  driver_info->DumpToLog();
37  EXPECT_TRUE(log.str().find("Driver Information") != std::string::npos);
38 }
39 
40 TEST(DriverInfoVKTest, CanIdentifyBadMaleoonDriver) {
41  auto const context =
42  MockVulkanContextBuilder()
43  .SetPhysicalPropertiesCallback(
44  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
45  prop->vendorID = 0x19E5; // Huawei
46  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
47  })
48  .Build();
49 
50  EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
51 }
52 
53 bool IsBadVersionTest(std::string_view driver_name, bool qc = true) {
54  auto const context =
55  MockVulkanContextBuilder()
56  .SetPhysicalPropertiesCallback(
57  [&driver_name, qc](VkPhysicalDevice device,
58  VkPhysicalDeviceProperties* prop) {
59  if (qc) {
60  prop->vendorID = 0x168C; // Qualcomm
61  } else {
62  prop->vendorID = 0x13B5; // ARM
63  }
64  driver_name.copy(prop->deviceName, driver_name.size());
65  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
66  })
67  .Build();
68  return context->GetDriverInfo()->IsKnownBadDriver();
69 }
70 
71 bool CanBatchSubmitTest(std::string_view driver_name, bool qc = true) {
72  auto const context =
73  MockVulkanContextBuilder()
74  .SetPhysicalPropertiesCallback(
75  [&driver_name, qc](VkPhysicalDevice device,
76  VkPhysicalDeviceProperties* prop) {
77  if (qc) {
78  prop->vendorID = 0x168C; // Qualcomm
79  } else {
80  prop->vendorID = 0x13B5; // ARM
81  }
82  driver_name.copy(prop->deviceName, driver_name.size());
83  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
84  })
85  .Build();
86  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
88 }
89 
90 TEST(DriverInfoVKTest, CanBatchSubmitCommandBuffers) {
91  // Old Adreno no batch submit!
92  EXPECT_FALSE(CanBatchSubmitTest("Adreno (TM) 540", true));
93 
94  EXPECT_TRUE(CanBatchSubmitTest("Mali-G51", false));
95  EXPECT_TRUE(CanBatchSubmitTest("Adreno (TM) 750", true));
96 }
97 
98 bool CanUsePrimitiveRestartSubmitTest(std::string_view driver_name,
99  bool qc = true) {
100  auto const context =
101  MockVulkanContextBuilder()
102  .SetPhysicalPropertiesCallback(
103  [&driver_name, qc](VkPhysicalDevice device,
104  VkPhysicalDeviceProperties* prop) {
105  if (qc) {
106  prop->vendorID = 0x168C; // Qualcomm
107  } else {
108  prop->vendorID = 0x13B5; // ARM
109  }
110  driver_name.copy(prop->deviceName, driver_name.size());
111  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
112  })
113  .Build();
114  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
116 }
117 
118 TEST(DriverInfoVKTest, CanUsePrimitiveRestart) {
119  // Adreno no primitive restart
120  EXPECT_FALSE(CanUsePrimitiveRestartSubmitTest("Adreno (TM) 540", true));
121  EXPECT_FALSE(CanUsePrimitiveRestartSubmitTest("Adreno (TM) 750", true));
122 
123  // Mali A-OK
124  EXPECT_TRUE(CanUsePrimitiveRestartSubmitTest("Mali-G51", false));
125 }
126 
127 bool CanUseMipgeneration(std::string_view driver_name, bool qc = true) {
128  auto const context =
129  MockVulkanContextBuilder()
130  .SetPhysicalPropertiesCallback(
131  [&driver_name, qc](VkPhysicalDevice device,
132  VkPhysicalDeviceProperties* prop) {
133  if (qc) {
134  prop->vendorID = 0x168C; // Qualcomm
135  } else {
136  prop->vendorID = 0x13B5; // ARM
137  }
138  driver_name.copy(prop->deviceName, driver_name.size());
139  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
140  })
141  .Build();
142  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
144 }
145 
146 TEST(DriverInfoVKTest, CanGenerateMipMaps) {
147  // Adreno no mips
148  EXPECT_FALSE(CanUseMipgeneration("Adreno (TM) 540", true));
149  EXPECT_FALSE(CanUseMipgeneration("Adreno (TM) 750", true));
150 
151  // Mali A-OK
152  EXPECT_TRUE(CanUseMipgeneration("Mali-G51", false));
153 }
154 
155 TEST(DriverInfoVKTest, DriverParsingMali) {
156  EXPECT_EQ(GetMaliVersion("Mali-G51-MORE STUFF"), MaliGPU::kG51);
157  EXPECT_EQ(GetMaliVersion("Mali-G51"), MaliGPU::kG51);
158  EXPECT_EQ(GetMaliVersion("Mali-111111"), MaliGPU::kUnknown);
159 }
160 
161 TEST(DriverInfoVKTest, DriverParsingAdreno) {
162  EXPECT_EQ(GetAdrenoVersion("Adreno (TM) 540"), AdrenoGPU::kAdreno540);
163  EXPECT_EQ(GetAdrenoVersion("Foo Bar"), AdrenoGPU::kUnknown);
164 }
165 
166 TEST(DriverInfoVKTest, DisabledDevices) {
167  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 620"));
168  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 610"));
169  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 530"));
170  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 512"));
171  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 509"));
172  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 508"));
173  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 506"));
174  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 505"));
175  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 504"));
176  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 630"));
177  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 640"));
178  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 650"));
179 }
180 
181 TEST(DriverInfoVKTest, EnabledDevicesMali) {
182  EXPECT_FALSE(IsBadVersionTest("Mali-G52", /*qc=*/false));
183  EXPECT_FALSE(IsBadVersionTest("Mali-G54-MORE STUFF", /*qc=*/false));
184 }
185 
186 TEST(DriverInfoVKTest, EnabledDevicesAdreno) {
187  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 750"));
188  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 740"));
189  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 732"));
190  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 730"));
191  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 725"));
192  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 720"));
193  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 710"));
194  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 702"));
195 }
196 
197 bool CanUseFramebufferFetch(std::string_view driver_name, bool qc = true) {
198  auto const context =
199  MockVulkanContextBuilder()
200  .SetPhysicalPropertiesCallback(
201  [&driver_name, qc](VkPhysicalDevice device,
202  VkPhysicalDeviceProperties* prop) {
203  if (qc) {
204  prop->vendorID = 0x168C; // Qualcomm
205  } else {
206  prop->vendorID = 0x13B5; // ARM
207  }
208  driver_name.copy(prop->deviceName, driver_name.size());
209  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
210  })
211  .Build();
212  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
214 }
215 
217  // Adreno no primitive restart on models as or older than 630.
218  EXPECT_FALSE(CanUseFramebufferFetch("Adreno (TM) 540", true));
219  EXPECT_FALSE(CanUseFramebufferFetch("Adreno (TM) 630", true));
220 
221  EXPECT_TRUE(CanUseFramebufferFetch("Adreno (TM) 640", true));
222  EXPECT_TRUE(CanUseFramebufferFetch("Adreno (TM) 750", true));
223  EXPECT_TRUE(CanUseFramebufferFetch("Mali-G51", false));
224 }
225 
226 TEST(DriverInfoVKTest, DisableOldXclipseDriver) {
227  auto context =
228  MockVulkanContextBuilder()
229  .SetPhysicalPropertiesCallback(
230  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
231  prop->vendorID = 0x144D; // Samsung
232  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
233  // Version 1.1.0
234  prop->apiVersion = (1 << 22) | (1 << 12);
235  })
236  .Build();
237 
238  EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
239 
240  context =
241  MockVulkanContextBuilder()
242  .SetPhysicalPropertiesCallback(
243  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
244  prop->vendorID = 0x144D; // Samsung
245  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
246  // Version 1.3.0
247  prop->apiVersion = (1 << 22) | (3 << 12);
248  })
249  .Build();
250 
251  EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
252 }
253 
254 TEST(DriverInfoVKTest, OldPowerVRDisabled) {
255  std::shared_ptr<ContextVK> context =
256  MockVulkanContextBuilder()
257  .SetPhysicalPropertiesCallback(
258  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
259  prop->vendorID = 0x1010;
260  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
261  std::string name = "PowerVR Rogue GE8320";
262  name.copy(prop->deviceName, name.size());
263  })
264  .Build();
265 
266  EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
267  EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
268  std::optional<PowerVRGPU>(PowerVRGPU::kUnknown));
269 }
270 
271 TEST(DriverInfoVKTest, NewPowerVREnabled) {
272  std::shared_ptr<ContextVK> context =
273  MockVulkanContextBuilder()
274  .SetPhysicalPropertiesCallback(
275  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
276  prop->vendorID = 0x1010;
277  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
278  std::string name = "PowerVR DXT 123";
279  name.copy(prop->deviceName, name.size());
280  })
281  .Build();
282 
283  EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
284  EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
285  std::optional<PowerVRGPU>(PowerVRGPU::kDXT));
286  EXPECT_TRUE(GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
288 }
289 
290 } // namespace impeller::testing
static SurfaceContextVK & Cast(Context &base)
Definition: backend_cast.h:13
const std::shared_ptr< ContextVK > & GetParent() const
bool CanUseFramebufferFetch(std::string_view driver_name, bool qc=true)
TEST(AllocationSizeTest, CanCreateTypedAllocations)
bool CanUseMipgeneration(std::string_view driver_name, bool qc=true)
TEST_P(AiksTest, DrawAtlasNoColor)
bool IsBadVersionTest(std::string_view driver_name, bool qc=true)
INSTANTIATE_VULKAN_PLAYGROUND_SUITE(DriverInfoVKTest)
bool CanUsePrimitiveRestartSubmitTest(std::string_view driver_name, bool qc=true)
bool CanBatchSubmitTest(std::string_view driver_name, bool qc=true)
MaliGPU GetMaliVersion(std::string_view version)
AdrenoGPU GetAdrenoVersion(std::string_view version)
WorkaroundsVK GetWorkaroundsFromDriverInfo(DriverInfoVK &driver_info)
bool input_attachment_self_dependency_broken