| 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
5 #include "impeller/playground/playground_test.h"
6 #include "impeller/renderer/backend/vulkan/context_vk.h"
7 #include "impeller/renderer/backend/vulkan/driver_info_vk.h"
8 #include "impeller/renderer/backend/vulkan/surface_context_vk.h"
9 #include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
10 #include "impeller/renderer/backend/vulkan/workarounds_vk.h"
11
12 namespace impeller::testing {
13
14 using DriverInfoVKTest = PlaygroundTest;
15 INSTANTIATE_VULKAN_PLAYGROUND_SUITE(DriverInfoVKTest);
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())
87 .batch_submit_command_buffer_timeout;
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())
115 .slow_primitive_restart_performance;
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())
143 .broken_mipmap_generation;
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_TRUE(IsBadVersionTest("Adreno (TM) 620"));
168 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 610"));
169 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 530"));
170 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 512"));
171 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 509"));
172 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 508"));
173 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 506"));
174 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 505"));
175 EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 504"));
176 EXPECT_TRUE(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())
213 .input_attachment_self_dependency_broken;
214 }
215
216 TEST(DriverInfoVKTest, CanUseFramebufferFetch) {
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())
287 .input_attachment_self_dependency_broken);
288 }
289
290 TEST(DriverInfoVKTest, PowerVRBSeries) {
291 std::shared_ptr<ContextVK> context =
292 MockVulkanContextBuilder()
293 .SetPhysicalPropertiesCallback(
294 [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
295 prop->vendorID = 0x1010;
296 prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
297 std::string name = "PowerVR BXM-8-256";
298 name.copy(prop->deviceName, name.size());
299 })
300 .Build();
301
302 EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
303 EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
304 std::optional<PowerVRGPU>(PowerVRGPU::kBXM));
305 }
306
307 } // namespace impeller::testing
impeller::BackendCast< SurfaceContextVK, Context >::Cast
static SurfaceContextVK & Cast(Context &base)
Definition: backend_cast.h:13
impeller::PlaygroundTest
Definition: playground_test.h:22
impeller::SurfaceContextVK::GetParent
const std::shared_ptr< ContextVK > & GetParent() const
Definition: surface_context_vk.cc:126
driver_info_vk.h
impeller::testing
Definition: allocation_size_unittests.cc:8
impeller::testing::CanUseFramebufferFetch
bool CanUseFramebufferFetch(std::string_view driver_name, bool qc=true)
Definition: driver_info_vk_unittests.cc:197
impeller::testing::TEST
TEST(AllocationSizeTest, CanCreateTypedAllocations)
Definition: allocation_size_unittests.cc:10
impeller::testing::CanUseMipgeneration
bool CanUseMipgeneration(std::string_view driver_name, bool qc=true)
Definition: driver_info_vk_unittests.cc:127
impeller::testing::TEST_P
TEST_P(AiksTest, DrawAtlasNoColor)
Definition: aiks_dl_atlas_unittests.cc:59
impeller::testing::IsBadVersionTest
bool IsBadVersionTest(std::string_view driver_name, bool qc=true)
Definition: driver_info_vk_unittests.cc:53
impeller::testing::INSTANTIATE_VULKAN_PLAYGROUND_SUITE
INSTANTIATE_VULKAN_PLAYGROUND_SUITE(DriverInfoVKTest)
impeller::testing::CanUsePrimitiveRestartSubmitTest
bool CanUsePrimitiveRestartSubmitTest(std::string_view driver_name, bool qc=true)
Definition: driver_info_vk_unittests.cc:98
impeller::testing::CanBatchSubmitTest
bool CanBatchSubmitTest(std::string_view driver_name, bool qc=true)
Definition: driver_info_vk_unittests.cc:71
impeller::MaliGPU::kUnknown
@ kUnknown
impeller::MaliGPU::kG51
@ kG51
impeller::VendorVK::kUnknown
@ kUnknown
impeller::AdrenoGPU::kUnknown
@ kUnknown
impeller::AdrenoGPU::kAdreno540
@ kAdreno540
impeller::PowerVRGPU::kUnknown
@ kUnknown
impeller::PowerVRGPU::kDXT
@ kDXT
impeller::PowerVRGPU::kBXM
@ kBXM
impeller::GetMaliVersion
MaliGPU GetMaliVersion(std::string_view version)
Definition: driver_info_vk.cc:144
impeller::GetAdrenoVersion
AdrenoGPU GetAdrenoVersion(std::string_view version)
Definition: driver_info_vk.cc:120
impeller::DeviceTypeVK::kUnknown
@ kUnknown
impeller::GetWorkaroundsFromDriverInfo
WorkaroundsVK GetWorkaroundsFromDriverInfo(DriverInfoVK &driver_info)
Definition: workarounds_vk.cc:10
playground_test.h
context_vk.h
impeller::Version
Definition: version.h:16
impeller::WorkaroundsVK::broken_mipmap_generation
bool broken_mipmap_generation
Definition: workarounds_vk.h:38
impeller::WorkaroundsVK::batch_submit_command_buffer_timeout
bool batch_submit_command_buffer_timeout
Definition: workarounds_vk.h:24
impeller::WorkaroundsVK::slow_primitive_restart_performance
bool slow_primitive_restart_performance
Definition: workarounds_vk.h:18
impeller::WorkaroundsVK::input_attachment_self_dependency_broken
bool input_attachment_self_dependency_broken
Definition: workarounds_vk.h:30
surface_context_vk.h
workarounds_vk.h