1 // Copyright (c) 2012 The Chromium 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 "gpu/config/gpu_test_config.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include "base/command_line.h"
11 #include "base/logging.h"
12 #include "base/system/sys_info.h"
13 #include "build/build_config.h"
14 #include "build/chromeos_buildflags.h"
15 #include "gpu/config/gpu_info.h"
16 #include "gpu/config/gpu_info_collector.h"
17 #include "gpu/config/gpu_test_expectations_parser.h"
18 #include "ui/gl/gl_utils.h"
19
20 #if defined(OS_WIN)
21 #include "base/win/windows_version.h"
22 #endif
23
24 namespace gpu {
25
26 namespace {
27
GetCurrentOS()28 GPUTestConfig::OS GetCurrentOS() {
29 #if BUILDFLAG(IS_ASH)
30 return GPUTestConfig::kOsChromeOS;
31 #elif defined(OS_LINUX) || defined(OS_BSD)
32 return GPUTestConfig::kOsLinux;
33 #elif defined(OS_WIN)
34 int32_t major_version = 0;
35 int32_t minor_version = 0;
36 int32_t bugfix_version = 0;
37 base::SysInfo::OperatingSystemVersionNumbers(
38 &major_version, &minor_version, &bugfix_version);
39 if (major_version == 5)
40 return GPUTestConfig::kOsWinXP;
41 if (major_version == 6 && minor_version == 0)
42 return GPUTestConfig::kOsWinVista;
43 if (major_version == 6 && minor_version == 1)
44 return GPUTestConfig::kOsWin7;
45 if (major_version == 6 && (minor_version == 2 || minor_version == 3))
46 return GPUTestConfig::kOsWin8;
47 if (major_version == 10)
48 return GPUTestConfig::kOsWin10;
49 return GPUTestConfig::kOsUnknown;
50 #elif defined(OS_MAC)
51 int32_t major_version = 0;
52 int32_t minor_version = 0;
53 int32_t bugfix_version = 0;
54 base::SysInfo::OperatingSystemVersionNumbers(
55 &major_version, &minor_version, &bugfix_version);
56 switch (major_version) {
57 case 10:
58 switch (minor_version) {
59 case 5:
60 return GPUTestConfig::kOsMacLeopard;
61 case 6:
62 return GPUTestConfig::kOsMacSnowLeopard;
63 case 7:
64 return GPUTestConfig::kOsMacLion;
65 case 8:
66 return GPUTestConfig::kOsMacMountainLion;
67 case 9:
68 return GPUTestConfig::kOsMacMavericks;
69 case 10:
70 return GPUTestConfig::kOsMacYosemite;
71 case 11:
72 return GPUTestConfig::kOsMacElCapitan;
73 case 12:
74 return GPUTestConfig::kOsMacSierra;
75 case 13:
76 return GPUTestConfig::kOsMacHighSierra;
77 case 14:
78 return GPUTestConfig::kOsMacMojave;
79 case 15:
80 return GPUTestConfig::kOsMacCatalina;
81 }
82 break;
83 case 11:
84 switch (minor_version) {
85 case 0:
86 return GPUTestConfig::kOsMacBigSur;
87 }
88 break;
89 }
90 return GPUTestConfig::kOsUnknown;
91 #elif defined(OS_ANDROID)
92 return GPUTestConfig::kOsAndroid;
93 #elif defined(OS_FUCHSIA)
94 return GPUTestConfig::kOsFuchsia;
95 #else
96 #error "unknown os"
97 #endif
98 }
99
100 } // namespace anonymous
101
GPUTestConfig()102 GPUTestConfig::GPUTestConfig()
103 : os_(kOsUnknown),
104 gpu_device_id_(0),
105 build_type_(kBuildTypeUnknown),
106 api_(kAPIUnknown),
107 command_decoder_(kCommandDecoderUnknown) {}
108
109 GPUTestConfig::GPUTestConfig(const GPUTestConfig& other) = default;
110
111 GPUTestConfig::~GPUTestConfig() = default;
112
set_os(int32_t os)113 void GPUTestConfig::set_os(int32_t os) {
114 DCHECK_EQ(0, os & ~(kOsAndroid | kOsWin | kOsMac | kOsLinux | kOsChromeOS |
115 kOsFuchsia));
116 os_ = os;
117 }
118
AddGPUVendor(uint32_t gpu_vendor)119 void GPUTestConfig::AddGPUVendor(uint32_t gpu_vendor) {
120 DCHECK_NE(0u, gpu_vendor);
121 for (size_t i = 0; i < gpu_vendor_.size(); ++i)
122 DCHECK_NE(gpu_vendor_[i], gpu_vendor);
123 gpu_vendor_.push_back(gpu_vendor);
124 }
125
set_gpu_device_id(uint32_t id)126 void GPUTestConfig::set_gpu_device_id(uint32_t id) {
127 gpu_device_id_ = id;
128 }
129
set_build_type(int32_t build_type)130 void GPUTestConfig::set_build_type(int32_t build_type) {
131 DCHECK_EQ(0, build_type & ~(kBuildTypeRelease | kBuildTypeDebug));
132 build_type_ = build_type;
133 }
134
set_api(int32_t api)135 void GPUTestConfig::set_api(int32_t api) {
136 DCHECK_EQ(0, api & ~(kAPID3D9 | kAPID3D11 | kAPIGLDesktop | kAPIGLES));
137 api_ = api;
138 }
139
set_command_decoder(int32_t command_decoder)140 void GPUTestConfig::set_command_decoder(int32_t command_decoder) {
141 DCHECK_EQ(0, command_decoder &
142 ~(kCommandDecoderPassthrough | kCommandDecoderValidating));
143 command_decoder_ = command_decoder;
144 }
145
IsValid() const146 bool GPUTestConfig::IsValid() const {
147 if (gpu_device_id_ != 0 && (gpu_vendor_.size() != 1 || gpu_vendor_[0] == 0))
148 return false;
149 return true;
150 }
151
OverlapsWith(const GPUTestConfig & config) const152 bool GPUTestConfig::OverlapsWith(const GPUTestConfig& config) const {
153 DCHECK(IsValid());
154 DCHECK(config.IsValid());
155 if (config.os_ != kOsUnknown && os_ != kOsUnknown &&
156 (os_ & config.os_) == 0)
157 return false;
158 if (config.gpu_vendor_.size() > 0 && gpu_vendor_.size() > 0) {
159 bool shared = false;
160 for (size_t i = 0; i < config.gpu_vendor_.size() && !shared; ++i) {
161 for (size_t j = 0; j < gpu_vendor_.size(); ++j) {
162 if (config.gpu_vendor_[i] == gpu_vendor_[j]) {
163 shared = true;
164 break;
165 }
166 }
167 }
168 if (!shared)
169 return false;
170 }
171 if (config.gpu_device_id_ != 0 && gpu_device_id_ != 0 &&
172 gpu_device_id_ != config.gpu_device_id_)
173 return false;
174 if (config.build_type_ != kBuildTypeUnknown &&
175 build_type_ != kBuildTypeUnknown &&
176 (build_type_ & config.build_type_) == 0)
177 return false;
178 if (config.api() != kAPIUnknown && api_ != kAPIUnknown && api_ != config.api_)
179 return false;
180 return true;
181 }
182
ClearGPUVendor()183 void GPUTestConfig::ClearGPUVendor() {
184 gpu_vendor_.clear();
185 }
186
187 GPUTestBotConfig::~GPUTestBotConfig() = default;
188
AddGPUVendor(uint32_t gpu_vendor)189 void GPUTestBotConfig::AddGPUVendor(uint32_t gpu_vendor) {
190 DCHECK_EQ(0u, GPUTestConfig::gpu_vendor().size());
191 GPUTestConfig::AddGPUVendor(gpu_vendor);
192 }
193
SetGPUInfo(const GPUInfo & gpu_info)194 bool GPUTestBotConfig::SetGPUInfo(const GPUInfo& gpu_info) {
195 if (gpu_info.gpu.vendor_id == 0)
196 return false;
197 #if !defined(OS_MAC)
198 // ARM-based Mac GPUs do not have valid PCI device IDs.
199 // https://crbug.com/1110421
200 if (gpu_info.gpu.device_id == 0)
201 return false;
202 #endif
203 ClearGPUVendor();
204 AddGPUVendor(gpu_info.gpu.vendor_id);
205 set_gpu_device_id(gpu_info.gpu.device_id);
206 if (gpu_info.passthrough_cmd_decoder) {
207 set_command_decoder(kCommandDecoderPassthrough);
208 } else {
209 set_command_decoder(kCommandDecoderValidating);
210 }
211 return true;
212 }
213
IsValid() const214 bool GPUTestBotConfig::IsValid() const {
215 switch (os()) {
216 case kOsWinXP:
217 case kOsWinVista:
218 case kOsWin7:
219 case kOsWin8:
220 case kOsWin10:
221 case kOsMacLeopard:
222 case kOsMacSnowLeopard:
223 case kOsMacLion:
224 case kOsMacMountainLion:
225 case kOsMacMavericks:
226 case kOsMacYosemite:
227 case kOsMacElCapitan:
228 case kOsMacSierra:
229 case kOsMacHighSierra:
230 case kOsMacMojave:
231 case kOsMacCatalina:
232 case kOsMacBigSur:
233 case kOsLinux:
234 case kOsChromeOS:
235 case kOsAndroid:
236 case kOsFuchsia:
237 break;
238 default:
239 return false;
240 }
241 if (gpu_vendor().size() != 1 || gpu_vendor()[0] == 0)
242 return false;
243 if (!(os() & gpu::GPUTestConfig::kOsMac)) {
244 // ARM-based Mac GPUs do not have valid PCI device IDs.
245 // https://crbug.com/1110421
246 if (gpu_device_id() == 0)
247 return false;
248 }
249 switch (build_type()) {
250 case kBuildTypeRelease:
251 case kBuildTypeDebug:
252 break;
253 default:
254 return false;
255 }
256 return true;
257 }
258
Matches(const GPUTestConfig & config) const259 bool GPUTestBotConfig::Matches(const GPUTestConfig& config) const {
260 DCHECK(IsValid());
261 DCHECK(config.IsValid());
262 if (config.os() != kOsUnknown && (os() & config.os()) == 0)
263 return false;
264 if (config.gpu_vendor().size() > 0) {
265 bool contained = false;
266 for (size_t i = 0; i < config.gpu_vendor().size(); ++i) {
267 if (config.gpu_vendor()[i] == gpu_vendor()[0]) {
268 contained = true;
269 break;
270 }
271 }
272 if (!contained)
273 return false;
274 }
275 if (config.gpu_device_id() != 0 &&
276 gpu_device_id() != config.gpu_device_id())
277 return false;
278 if (config.build_type() != kBuildTypeUnknown &&
279 (build_type() & config.build_type()) == 0)
280 return false;
281 if (config.api() != 0 && (api() & config.api()) == 0)
282 return false;
283 if (config.command_decoder() != 0 &&
284 command_decoder() != config.command_decoder())
285 return false;
286 return true;
287 }
288
Matches(const std::string & config_data) const289 bool GPUTestBotConfig::Matches(const std::string& config_data) const {
290 GPUTestExpectationsParser parser;
291 GPUTestConfig config;
292
293 if (!parser.ParseConfig(config_data, &config))
294 return false;
295 return Matches(config);
296 }
297
LoadCurrentConfig(const GPUInfo * gpu_info)298 bool GPUTestBotConfig::LoadCurrentConfig(const GPUInfo* gpu_info) {
299 bool rt;
300 if (!gpu_info) {
301 #if defined(OS_ANDROID)
302 // TODO(zmo): Implement this.
303 rt = false;
304 #else
305 GPUInfo my_gpu_info;
306 if (!CollectBasicGraphicsInfo(base::CommandLine::ForCurrentProcess(),
307 &my_gpu_info)) {
308 LOG(ERROR) << "Fail to identify GPU";
309 rt = false;
310 } else {
311 rt = SetGPUInfo(my_gpu_info);
312 }
313 #endif // OS_ANDROID
314 } else {
315 rt = SetGPUInfo(*gpu_info);
316 }
317 set_os(GetCurrentOS());
318 if (os() == kOsUnknown) {
319 LOG(ERROR) << "Unknown OS";
320 rt = false;
321 }
322 #if defined(NDEBUG)
323 set_build_type(kBuildTypeRelease);
324 #else
325 set_build_type(kBuildTypeDebug);
326 #endif
327 return rt;
328 }
329
330 // static
CurrentConfigMatches(const std::string & config_data)331 bool GPUTestBotConfig::CurrentConfigMatches(const std::string& config_data) {
332 GPUTestBotConfig my_config;
333 if (!my_config.LoadCurrentConfig(nullptr))
334 return false;
335 return my_config.Matches(config_data);
336 }
337
338 // static
CurrentConfigMatches(const std::vector<std::string> & configs)339 bool GPUTestBotConfig::CurrentConfigMatches(
340 const std::vector<std::string>& configs) {
341 GPUTestBotConfig my_config;
342 if (!my_config.LoadCurrentConfig(nullptr))
343 return false;
344 for (size_t i = 0 ; i < configs.size(); ++i) {
345 if (my_config.Matches(configs[i]))
346 return true;
347 }
348 return false;
349 }
350
351 // static
GpuBlocklistedOnBot()352 bool GPUTestBotConfig::GpuBlocklistedOnBot() {
353 return false;
354 }
355
356 } // namespace gpu
357