1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // angle_test_instantiate.h: Adds support for filtering parameterized
8 // tests by platform, so we skip unsupported configs.
9
10 #ifndef ANGLE_TEST_INSTANTIATE_H_
11 #define ANGLE_TEST_INSTANTIATE_H_
12
13 #include <gtest/gtest.h>
14
15 #include "common/platform_helpers.h"
16
17 namespace angle
18 {
19 struct SystemInfo;
20 struct PlatformParameters;
21
22 // Operating systems
23 bool IsOzone();
24
25 // CPU architectures
26 bool IsARM64();
27
28 // Android devices
29 bool IsNexus5X();
30 bool IsNexus9();
31 bool IsPixelXL();
32 bool IsPixel2();
33 bool IsPixel2XL();
34 bool IsPixel4();
35 bool IsPixel4XL();
36 bool IsPixel6();
37 bool IsGalaxyS22();
38 bool IsNVIDIAShield();
39
40 // Android versions
41 bool IsAndroid14OrNewer();
42
43 // GPU vendors.
44 bool IsIntel();
45 bool IsAMD();
46 bool IsAppleGPU();
47 bool IsARM();
48 bool IsNVIDIA();
49 bool IsQualcomm();
50
51 // GPU devices.
52 bool IsSwiftshaderDevice();
53 bool IsIntelUHD630Mobile();
54
55 bool HasMesa();
56
57 bool IsPlatformAvailable(const PlatformParameters ¶m);
58
59 // This functions is used to filter which tests should be registered,
60 // T must be or inherit from angle::PlatformParameters.
61 template <typename T>
FilterTestParams(const T * params,size_t numParams)62 std::vector<T> FilterTestParams(const T *params, size_t numParams)
63 {
64 std::vector<T> filtered;
65
66 for (size_t i = 0; i < numParams; i++)
67 {
68 if (IsPlatformAvailable(params[i]))
69 {
70 filtered.push_back(params[i]);
71 }
72 }
73
74 return filtered;
75 }
76
77 template <typename T>
FilterTestParams(const std::vector<T> & params)78 std::vector<T> FilterTestParams(const std::vector<T> ¶ms)
79 {
80 return FilterTestParams(params.data(), params.size());
81 }
82
83 // Used to generate valid test names out of testing::PrintToStringParamName used in combined tests.
84 struct CombinedPrintToStringParamName
85 {
86 template <class ParamType>
operatorCombinedPrintToStringParamName87 std::string operator()(const testing::TestParamInfo<ParamType> &info) const
88 {
89 std::string name = testing::PrintToStringParamName()(info);
90 std::string sanitized;
91 for (const char c : name)
92 {
93 if (c == ',')
94 {
95 sanitized += '_';
96 }
97 else if (isalnum(c) || c == '_')
98 {
99 sanitized += c;
100 }
101 }
102 return sanitized;
103 }
104 };
105
106 #define ANGLE_INSTANTIATE_TEST_PLATFORMS(testName, ...) \
107 testing::ValuesIn(::angle::FilterTestParams(testName##__VA_ARGS__##params, \
108 ArraySize(testName##__VA_ARGS__##params)))
109
110 // Instantiate the test once for each extra argument. The types of all the
111 // arguments must match, and getRenderer must be implemented for that type.
112 #define ANGLE_INSTANTIATE_TEST(testName, first, ...) \
113 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
114 ##__VA_ARGS__}; \
115 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
116 testing::PrintToStringParamName())
117
118 #define ANGLE_INSTANTIATE_TEST_ARRAY(testName, valuesin) \
119 INSTANTIATE_TEST_SUITE_P(, testName, testing::ValuesIn(::angle::FilterTestParams(valuesin)), \
120 testing::PrintToStringParamName())
121
122 #if !defined(ANGLE_TEST_ENABLE_SYSTEM_EGL)
123 # define ANGLE_TEST_PLATFORMS_ES1_SYSTEM_EGL
124 # define ANGLE_TEST_PLATFORMS_ES2_SYSTEM_EGL
125 # define ANGLE_TEST_PLATFORMS_ES3_SYSTEM_EGL
126 # define ANGLE_TEST_PLATFORMS_ES31_SYSTEM_EGL
127 # define ANGLE_TEST_PLATFORMS_ES32_SYSTEM_EGL
128 #else
129 # define ANGLE_TEST_PLATFORMS_ES1_SYSTEM_EGL ES1_EGL(),
130 # define ANGLE_TEST_PLATFORMS_ES2_SYSTEM_EGL ES2_EGL(),
131 # define ANGLE_TEST_PLATFORMS_ES3_SYSTEM_EGL ES3_EGL(),
132 # define ANGLE_TEST_PLATFORMS_ES31_SYSTEM_EGL ES31_EGL(),
133 # define ANGLE_TEST_PLATFORMS_ES32_SYSTEM_EGL ES32_EGL(),
134 #endif
135
136 #define ANGLE_ALL_TEST_PLATFORMS_ES1 \
137 ANGLE_TEST_PLATFORMS_ES1_SYSTEM_EGL \
138 ES1_D3D11(), ES1_METAL(), ES1_OPENGL(), ES1_OPENGLES(), ES1_VULKAN(), \
139 ES1_VULKAN_SWIFTSHADER(), ES1_VULKAN().enable(Feature::AsyncCommandQueue), \
140 ES1_VULKAN().enable(Feature::EnableParallelCompileAndLink)
141
142 #define ANGLE_ALL_TEST_PLATFORMS_ES2 \
143 ANGLE_TEST_PLATFORMS_ES2_SYSTEM_EGL \
144 ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES(), ES2_VULKAN(), ES2_VULKAN_SWIFTSHADER(), \
145 ES2_METAL(), ES2_VULKAN().enable(Feature::AsyncCommandQueue), \
146 ES2_VULKAN_SWIFTSHADER().enable(Feature::EnableParallelCompileAndLink), \
147 ES2_VULKAN_SWIFTSHADER() \
148 .enable(Feature::EnableParallelCompileAndLink) \
149 .enable(Feature::AsyncCommandQueue) \
150 .disable(Feature::SupportsGraphicsPipelineLibrary)
151
152 #define ANGLE_ALL_TEST_PLATFORMS_ES3 \
153 ANGLE_TEST_PLATFORMS_ES3_SYSTEM_EGL \
154 ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER(), \
155 ES3_METAL(), ES3_VULKAN().enable(Feature::AsyncCommandQueue), \
156 ES3_VULKAN().enable(Feature::EnableParallelCompileAndLink), \
157 ES3_VULKAN_SWIFTSHADER() \
158 .enable(Feature::EnableParallelCompileAndLink) \
159 .enable(Feature::AsyncCommandQueue) \
160 .disable(Feature::SupportsGraphicsPipelineLibrary)
161
162 #define ANGLE_ALL_TEST_PLATFORMS_ES31 \
163 ANGLE_TEST_PLATFORMS_ES31_SYSTEM_EGL \
164 ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES(), ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER(), \
165 ES31_VULKAN().enable(Feature::AsyncCommandQueue), \
166 ES31_VULKAN_SWIFTSHADER() \
167 .enable(Feature::EnableParallelCompileAndLink) \
168 .enable(Feature::AsyncCommandQueue) \
169 .disable(Feature::SupportsGraphicsPipelineLibrary)
170
171 #define ANGLE_ALL_TEST_PLATFORMS_ES32 \
172 ANGLE_TEST_PLATFORMS_ES32_SYSTEM_EGL \
173 ES32_VULKAN(), ES32_VULKAN().enable(Feature::AsyncCommandQueue), \
174 ES32_VULKAN() \
175 .enable(Feature::AsyncCommandQueue) \
176 .enable(Feature::EnableParallelCompileAndLink)
177
178 #define ANGLE_ALL_TEST_PLATFORMS_NULL ES2_NULL(), ES3_NULL(), ES31_NULL()
179
180 // Instantiate the test once for each GLES1 platform
181 #define ANGLE_INSTANTIATE_TEST_ES1(testName) \
182 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES1}; \
183 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
184 testing::PrintToStringParamName())
185
186 // Instantiate the test once for each GLES2 platform
187 #define ANGLE_INSTANTIATE_TEST_ES2(testName) \
188 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2}; \
189 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
190 testing::PrintToStringParamName())
191
192 #define ANGLE_INSTANTIATE_TEST_ES2_AND(testName, ...) \
193 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, __VA_ARGS__}; \
194 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
195 testing::PrintToStringParamName())
196
197 // Instantiate the test once for each GLES3 platform
198 #define ANGLE_INSTANTIATE_TEST_ES3(testName) \
199 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3}; \
200 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
201 testing::PrintToStringParamName())
202
203 #define ANGLE_INSTANTIATE_TEST_ES3_AND(testName, ...) \
204 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3, __VA_ARGS__}; \
205 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
206 testing::PrintToStringParamName())
207
208 // Instantiate the test once for each GLES31 platform
209 #define ANGLE_INSTANTIATE_TEST_ES31(testName) \
210 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES31}; \
211 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
212 testing::PrintToStringParamName())
213
214 #define ANGLE_INSTANTIATE_TEST_ES31_AND(testName, ...) \
215 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES31, __VA_ARGS__}; \
216 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
217 testing::PrintToStringParamName())
218
219 // Instantiate the test once for each GLES32 platform
220 #define ANGLE_INSTANTIATE_TEST_ES32(testName) \
221 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES32}; \
222 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
223 testing::PrintToStringParamName())
224
225 #define ANGLE_INSTANTIATE_TEST_ES32_AND(testName, ...) \
226 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES32, __VA_ARGS__}; \
227 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
228 testing::PrintToStringParamName())
229
230 // Multiple ES Version macros
231 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(testName) \
232 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
233 ANGLE_ALL_TEST_PLATFORMS_ES3}; \
234 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
235 testing::PrintToStringParamName())
236
237 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(testName, ...) \
238 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
239 ANGLE_ALL_TEST_PLATFORMS_ES3, __VA_ARGS__}; \
240 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
241 testing::PrintToStringParamName())
242
243 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31(testName) \
244 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
245 ANGLE_ALL_TEST_PLATFORMS_ES3, \
246 ANGLE_ALL_TEST_PLATFORMS_ES31}; \
247 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
248 testing::PrintToStringParamName())
249
250 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND(testName, ...) \
251 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
252 ANGLE_ALL_TEST_PLATFORMS_ES3, \
253 ANGLE_ALL_TEST_PLATFORMS_ES31, __VA_ARGS__}; \
254 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
255 testing::PrintToStringParamName())
256
257 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND_ES32(testName, ...) \
258 const PlatformParameters testName##params[] = { \
259 ANGLE_ALL_TEST_PLATFORMS_ES2, ANGLE_ALL_TEST_PLATFORMS_ES3, ANGLE_ALL_TEST_PLATFORMS_ES31, \
260 ANGLE_ALL_TEST_PLATFORMS_ES32, __VA_ARGS__}; \
261 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
262 testing::PrintToStringParamName())
263
264 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND_NULL(testName) \
265 const PlatformParameters testName##params[] = { \
266 ANGLE_ALL_TEST_PLATFORMS_ES2, ANGLE_ALL_TEST_PLATFORMS_ES3, ANGLE_ALL_TEST_PLATFORMS_ES31, \
267 ANGLE_ALL_TEST_PLATFORMS_NULL}; \
268 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
269 testing::PrintToStringParamName())
270
271 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND_NULL_AND(testName, ...) \
272 const PlatformParameters testName##params[] = { \
273 ANGLE_ALL_TEST_PLATFORMS_ES2, ANGLE_ALL_TEST_PLATFORMS_ES3, ANGLE_ALL_TEST_PLATFORMS_ES31, \
274 ANGLE_ALL_TEST_PLATFORMS_NULL, __VA_ARGS__}; \
275 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
276 testing::PrintToStringParamName())
277
278 #define ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(testName) \
279 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3, \
280 ANGLE_ALL_TEST_PLATFORMS_ES31}; \
281 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
282 testing::PrintToStringParamName())
283
284 #define ANGLE_INSTANTIATE_TEST_ES3_AND_ES31_AND(testName, ...) \
285 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3, \
286 ANGLE_ALL_TEST_PLATFORMS_ES31, __VA_ARGS__}; \
287 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
288 testing::PrintToStringParamName())
289
290 // Instantiate the test for a combination of N parameters and the
291 // enumeration of platforms in the extra args, similar to
292 // ANGLE_INSTANTIATE_TEST. The macros are defined only for the Ns
293 // currently in use, and can be expanded as necessary.
294 #define ANGLE_INSTANTIATE_TEST_COMBINE_1(testName, print, combine1, first, ...) \
295 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
296 ##__VA_ARGS__}; \
297 INSTANTIATE_TEST_SUITE_P( \
298 , testName, testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), combine1), print)
299 #define ANGLE_INSTANTIATE_TEST_COMBINE_2(testName, print, combine1, combine2, first, ...) \
300 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
301 ##__VA_ARGS__}; \
302 INSTANTIATE_TEST_SUITE_P( \
303 , testName, \
304 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), combine1, combine2), print)
305 #define ANGLE_INSTANTIATE_TEST_COMBINE_3(testName, print, combine1, combine2, combine3, first, \
306 ...) \
307 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
308 ##__VA_ARGS__}; \
309 INSTANTIATE_TEST_SUITE_P(, testName, \
310 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
311 combine1, combine2, combine3), \
312 print)
313 #define ANGLE_INSTANTIATE_TEST_COMBINE_4(testName, print, combine1, combine2, combine3, combine4, \
314 first, ...) \
315 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
316 ##__VA_ARGS__}; \
317 INSTANTIATE_TEST_SUITE_P(, testName, \
318 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
319 combine1, combine2, combine3, combine4), \
320 print)
321 #define ANGLE_INSTANTIATE_TEST_COMBINE_5(testName, print, combine1, combine2, combine3, combine4, \
322 combine5, first, ...) \
323 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
324 ##__VA_ARGS__}; \
325 INSTANTIATE_TEST_SUITE_P(, testName, \
326 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
327 combine1, combine2, combine3, combine4, combine5), \
328 print)
329 #define ANGLE_INSTANTIATE_TEST_COMBINE_6(testName, print, combine1, combine2, combine3, combine4, \
330 combine5, combine6, first, ...) \
331 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
332 ##__VA_ARGS__}; \
333 INSTANTIATE_TEST_SUITE_P( \
334 , testName, \
335 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), combine1, combine2, combine3, \
336 combine4, combine5, combine6), \
337 print)
338
339 // Checks if a config is expected to be supported by checking a system-based allow list.
340 bool IsConfigAllowlisted(const SystemInfo &systemInfo, const PlatformParameters ¶m);
341
342 // Determines if a config is supported by trying to initialize it. Does
343 // not require SystemInfo.
344 bool IsConfigSupported(const PlatformParameters ¶m);
345
346 // Returns shared test system information. Can be used globally in the
347 // tests.
348 SystemInfo *GetTestSystemInfo();
349
350 // Returns a list of all enabled test platform names. For use in
351 // configuration enumeration.
352 std::vector<std::string> GetAvailableTestPlatformNames();
353
354 // Active config (e.g. ES2_Vulkan).
355 void SetSelectedConfig(const char *selectedConfig);
356 bool IsConfigSelected();
357
358 // Check whether texture swizzle is natively supported on Metal device.
359 bool IsMetalTextureSwizzleAvailable();
360
361 extern bool gEnableANGLEPerTestCaptureLabel;
362
363 // For use with ANGLE_INSTANTIATE_TEST_ARRAY
364 template <typename ParamsT>
365 using ModifierFunc = std::function<ParamsT(const ParamsT &)>;
366
367 template <typename ParamsT>
CombineWithFuncs(const std::vector<ParamsT> & in,const std::vector<ModifierFunc<ParamsT>> & modifiers)368 std::vector<ParamsT> CombineWithFuncs(const std::vector<ParamsT> &in,
369 const std::vector<ModifierFunc<ParamsT>> &modifiers)
370 {
371 std::vector<ParamsT> out;
372 for (const ParamsT ¶msIn : in)
373 {
374 for (ModifierFunc<ParamsT> modifier : modifiers)
375 {
376 out.push_back(modifier(paramsIn));
377 }
378 }
379 return out;
380 }
381
382 template <typename ParamT, typename RangeT, typename ModifierT>
CombineWithValues(const std::vector<ParamT> & in,RangeT begin,RangeT end,ParamT combine (const ParamT &,ModifierT))383 std::vector<ParamT> CombineWithValues(const std::vector<ParamT> &in,
384 RangeT begin,
385 RangeT end,
386 ParamT combine(const ParamT &, ModifierT))
387 {
388 std::vector<ParamT> out;
389 for (const ParamT ¶msIn : in)
390 {
391 for (auto iter = begin; iter != end; ++iter)
392 {
393 out.push_back(combine(paramsIn, *iter));
394 }
395 }
396 return out;
397 }
398
399 template <typename ParamT, typename ModifierT>
CombineWithValues(const std::vector<ParamT> & in,const std::initializer_list<ModifierT> & modifiers,ParamT combine (const ParamT &,ModifierT))400 std::vector<ParamT> CombineWithValues(const std::vector<ParamT> &in,
401 const std::initializer_list<ModifierT> &modifiers,
402 ParamT combine(const ParamT &, ModifierT))
403 {
404 return CombineWithValues(in, modifiers.begin(), modifiers.end(), combine);
405 }
406
407 template <typename ParamT, typename ModifiersT, typename ModifierT>
CombineWithValues(const std::vector<ParamT> & in,const ModifiersT & modifiers,ParamT combine (const ParamT &,ModifierT))408 std::vector<ParamT> CombineWithValues(const std::vector<ParamT> &in,
409 const ModifiersT &modifiers,
410 ParamT combine(const ParamT &, ModifierT))
411 {
412 return CombineWithValues(in, std::begin(modifiers), std::end(modifiers), combine);
413 }
414
415 template <typename ParamT, typename FilterFunc>
FilterWithFunc(const std::vector<ParamT> & in,FilterFunc filter)416 std::vector<ParamT> FilterWithFunc(const std::vector<ParamT> &in, FilterFunc filter)
417 {
418 std::vector<ParamT> out;
419 for (const ParamT ¶m : in)
420 {
421 if (filter(param))
422 {
423 out.push_back(param);
424 }
425 }
426 return out;
427 }
428 } // namespace angle
429
430 #define ANGLE_SKIP_TEST_IF(COND) \
431 do \
432 { \
433 if (COND) \
434 { \
435 GTEST_SKIP() << "Test skipped: " #COND "."; \
436 return; \
437 } \
438 } while (0)
439
440 #endif // ANGLE_TEST_INSTANTIATE_H_
441