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::EnableParallelCompileAndLink)
140
141 #define ANGLE_ALL_TEST_PLATFORMS_ES2 \
142 ANGLE_TEST_PLATFORMS_ES2_SYSTEM_EGL \
143 ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES(), ES2_VULKAN(), ES2_VULKAN_SWIFTSHADER(), \
144 ES2_METAL(), \
145 ES2_VULKAN() \
146 .enable(Feature::EnableParallelCompileAndLink) \
147 .enable(Feature::VaryingsRequireMatchingPrecisionInSpirv), \
148 ES2_VULKAN_SWIFTSHADER() \
149 .enable(Feature::EnableParallelCompileAndLink) \
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(), \
156 ES3_VULKAN() \
157 .enable(Feature::EnableParallelCompileAndLink) \
158 .enable(Feature::VaryingsRequireMatchingPrecisionInSpirv), \
159 ES3_VULKAN_SWIFTSHADER() \
160 .enable(Feature::EnableParallelCompileAndLink) \
161 .disable(Feature::SupportsGraphicsPipelineLibrary) \
162 .enable(Feature::VaryingsRequireMatchingPrecisionInSpirv)
163
164 #define ANGLE_ALL_TEST_PLATFORMS_ES31 \
165 ANGLE_TEST_PLATFORMS_ES31_SYSTEM_EGL \
166 ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES(), ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER(), \
167 ES31_VULKAN() \
168 .enable(Feature::EnableParallelCompileAndLink) \
169 .enable(Feature::VaryingsRequireMatchingPrecisionInSpirv), \
170 ES31_VULKAN_SWIFTSHADER() \
171 .enable(Feature::EnableParallelCompileAndLink) \
172 .disable(Feature::SupportsGraphicsPipelineLibrary) \
173 .enable(Feature::VaryingsRequireMatchingPrecisionInSpirv)
174
175 #define ANGLE_ALL_TEST_PLATFORMS_ES32 \
176 ANGLE_TEST_PLATFORMS_ES32_SYSTEM_EGL \
177 ES32_VULKAN(), ES32_VULKAN() \
178 .enable(Feature::EnableParallelCompileAndLink) \
179 .enable(Feature::VaryingsRequireMatchingPrecisionInSpirv)
180
181 #define ANGLE_ALL_TEST_PLATFORMS_NULL ES2_NULL(), ES3_NULL(), ES31_NULL()
182
183 // Instantiate the test once for each GLES1 platform
184 #define ANGLE_INSTANTIATE_TEST_ES1(testName) \
185 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES1}; \
186 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
187 testing::PrintToStringParamName())
188
189 // Instantiate the test once for each GLES2 platform
190 #define ANGLE_INSTANTIATE_TEST_ES2(testName) \
191 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2}; \
192 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
193 testing::PrintToStringParamName())
194
195 #define ANGLE_INSTANTIATE_TEST_ES2_AND(testName, ...) \
196 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, __VA_ARGS__}; \
197 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
198 testing::PrintToStringParamName())
199
200 // Instantiate the test once for each GLES3 platform
201 #define ANGLE_INSTANTIATE_TEST_ES3(testName) \
202 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3}; \
203 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
204 testing::PrintToStringParamName())
205
206 #define ANGLE_INSTANTIATE_TEST_ES3_AND(testName, ...) \
207 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3, __VA_ARGS__}; \
208 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
209 testing::PrintToStringParamName())
210
211 // Instantiate the test once for each GLES31 platform
212 #define ANGLE_INSTANTIATE_TEST_ES31(testName) \
213 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES31}; \
214 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
215 testing::PrintToStringParamName())
216
217 #define ANGLE_INSTANTIATE_TEST_ES31_AND(testName, ...) \
218 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES31, __VA_ARGS__}; \
219 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
220 testing::PrintToStringParamName())
221
222 // Instantiate the test once for each GLES32 platform
223 #define ANGLE_INSTANTIATE_TEST_ES32(testName) \
224 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES32}; \
225 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
226 testing::PrintToStringParamName())
227
228 #define ANGLE_INSTANTIATE_TEST_ES32_AND(testName, ...) \
229 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES32, __VA_ARGS__}; \
230 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
231 testing::PrintToStringParamName())
232
233 // Multiple ES Version macros
234 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(testName) \
235 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
236 ANGLE_ALL_TEST_PLATFORMS_ES3}; \
237 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
238 testing::PrintToStringParamName())
239
240 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(testName, ...) \
241 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
242 ANGLE_ALL_TEST_PLATFORMS_ES3, __VA_ARGS__}; \
243 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
244 testing::PrintToStringParamName())
245
246 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31(testName) \
247 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
248 ANGLE_ALL_TEST_PLATFORMS_ES3, \
249 ANGLE_ALL_TEST_PLATFORMS_ES31}; \
250 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
251 testing::PrintToStringParamName())
252
253 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND(testName, ...) \
254 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES2, \
255 ANGLE_ALL_TEST_PLATFORMS_ES3, \
256 ANGLE_ALL_TEST_PLATFORMS_ES31, __VA_ARGS__}; \
257 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
258 testing::PrintToStringParamName())
259
260 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND_ES32(testName, ...) \
261 const PlatformParameters testName##params[] = { \
262 ANGLE_ALL_TEST_PLATFORMS_ES2, ANGLE_ALL_TEST_PLATFORMS_ES3, ANGLE_ALL_TEST_PLATFORMS_ES31, \
263 ANGLE_ALL_TEST_PLATFORMS_ES32, __VA_ARGS__}; \
264 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
265 testing::PrintToStringParamName())
266
267 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND_NULL(testName) \
268 const PlatformParameters testName##params[] = { \
269 ANGLE_ALL_TEST_PLATFORMS_ES2, ANGLE_ALL_TEST_PLATFORMS_ES3, ANGLE_ALL_TEST_PLATFORMS_ES31, \
270 ANGLE_ALL_TEST_PLATFORMS_NULL}; \
271 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
272 testing::PrintToStringParamName())
273
274 #define ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND_NULL_AND(testName, ...) \
275 const PlatformParameters testName##params[] = { \
276 ANGLE_ALL_TEST_PLATFORMS_ES2, ANGLE_ALL_TEST_PLATFORMS_ES3, ANGLE_ALL_TEST_PLATFORMS_ES31, \
277 ANGLE_ALL_TEST_PLATFORMS_NULL, __VA_ARGS__}; \
278 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
279 testing::PrintToStringParamName())
280
281 #define ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(testName) \
282 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3, \
283 ANGLE_ALL_TEST_PLATFORMS_ES31}; \
284 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
285 testing::PrintToStringParamName())
286
287 #define ANGLE_INSTANTIATE_TEST_ES3_AND_ES31_AND(testName, ...) \
288 const PlatformParameters testName##params[] = {ANGLE_ALL_TEST_PLATFORMS_ES3, \
289 ANGLE_ALL_TEST_PLATFORMS_ES31, __VA_ARGS__}; \
290 INSTANTIATE_TEST_SUITE_P(, testName, ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
291 testing::PrintToStringParamName())
292
293 // Instantiate the test for a combination of N parameters and the
294 // enumeration of platforms in the extra args, similar to
295 // ANGLE_INSTANTIATE_TEST. The macros are defined only for the Ns
296 // currently in use, and can be expanded as necessary.
297 #define ANGLE_INSTANTIATE_TEST_COMBINE_1(testName, print, combine1, first, ...) \
298 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
299 ##__VA_ARGS__}; \
300 INSTANTIATE_TEST_SUITE_P( \
301 , testName, testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), combine1), print)
302 #define ANGLE_INSTANTIATE_TEST_COMBINE_2(testName, print, combine1, combine2, first, ...) \
303 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
304 ##__VA_ARGS__}; \
305 INSTANTIATE_TEST_SUITE_P( \
306 , testName, \
307 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), combine1, combine2), print)
308 #define ANGLE_INSTANTIATE_TEST_COMBINE_3(testName, print, combine1, combine2, combine3, first, \
309 ...) \
310 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
311 ##__VA_ARGS__}; \
312 INSTANTIATE_TEST_SUITE_P(, testName, \
313 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
314 combine1, combine2, combine3), \
315 print)
316 #define ANGLE_INSTANTIATE_TEST_COMBINE_4(testName, print, combine1, combine2, combine3, combine4, \
317 first, ...) \
318 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
319 ##__VA_ARGS__}; \
320 INSTANTIATE_TEST_SUITE_P(, testName, \
321 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
322 combine1, combine2, combine3, combine4), \
323 print)
324 #define ANGLE_INSTANTIATE_TEST_COMBINE_5(testName, print, combine1, combine2, combine3, combine4, \
325 combine5, first, ...) \
326 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
327 ##__VA_ARGS__}; \
328 INSTANTIATE_TEST_SUITE_P(, testName, \
329 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), \
330 combine1, combine2, combine3, combine4, combine5), \
331 print)
332 #define ANGLE_INSTANTIATE_TEST_COMBINE_6(testName, print, combine1, combine2, combine3, combine4, \
333 combine5, combine6, first, ...) \
334 const std::remove_reference<decltype(first)>::type testName##params[] = {first, \
335 ##__VA_ARGS__}; \
336 INSTANTIATE_TEST_SUITE_P( \
337 , testName, \
338 testing::Combine(ANGLE_INSTANTIATE_TEST_PLATFORMS(testName), combine1, combine2, combine3, \
339 combine4, combine5, combine6), \
340 print)
341
342 // Checks if a config is expected to be supported by checking a system-based allow list.
343 bool IsConfigAllowlisted(const SystemInfo &systemInfo, const PlatformParameters ¶m);
344
345 // Determines if a config is supported by trying to initialize it. Does
346 // not require SystemInfo.
347 bool IsConfigSupported(const PlatformParameters ¶m);
348
349 // Returns shared test system information. Can be used globally in the
350 // tests.
351 SystemInfo *GetTestSystemInfo();
352
353 // Returns a list of all enabled test platform names. For use in
354 // configuration enumeration.
355 std::vector<std::string> GetAvailableTestPlatformNames();
356
357 // Active config (e.g. ES2_Vulkan).
358 void SetSelectedConfig(const char *selectedConfig);
359 bool IsConfigSelected();
360
361 // Check whether texture swizzle is natively supported on Metal device.
362 bool IsMetalTextureSwizzleAvailable();
363
364 extern bool gEnableANGLEPerTestCaptureLabel;
365
366 extern bool gEnableRenderDocCapture;
367
368 // For use with ANGLE_INSTANTIATE_TEST_ARRAY
369 template <typename ParamsT>
370 using ModifierFunc = std::function<ParamsT(const ParamsT &)>;
371
372 template <typename ParamsT>
CombineWithFuncs(const std::vector<ParamsT> & in,const std::vector<ModifierFunc<ParamsT>> & modifiers)373 std::vector<ParamsT> CombineWithFuncs(const std::vector<ParamsT> &in,
374 const std::vector<ModifierFunc<ParamsT>> &modifiers)
375 {
376 std::vector<ParamsT> out;
377 for (const ParamsT ¶msIn : in)
378 {
379 for (ModifierFunc<ParamsT> modifier : modifiers)
380 {
381 out.push_back(modifier(paramsIn));
382 }
383 }
384 return out;
385 }
386
387 template <typename ParamT, typename RangeT, typename ModifierT>
CombineWithValues(const std::vector<ParamT> & in,RangeT begin,RangeT end,ParamT combine (const ParamT &,ModifierT))388 std::vector<ParamT> CombineWithValues(const std::vector<ParamT> &in,
389 RangeT begin,
390 RangeT end,
391 ParamT combine(const ParamT &, ModifierT))
392 {
393 std::vector<ParamT> out;
394 for (const ParamT ¶msIn : in)
395 {
396 for (auto iter = begin; iter != end; ++iter)
397 {
398 out.push_back(combine(paramsIn, *iter));
399 }
400 }
401 return out;
402 }
403
404 template <typename ParamT, typename ModifierT>
CombineWithValues(const std::vector<ParamT> & in,const std::initializer_list<ModifierT> & modifiers,ParamT combine (const ParamT &,ModifierT))405 std::vector<ParamT> CombineWithValues(const std::vector<ParamT> &in,
406 const std::initializer_list<ModifierT> &modifiers,
407 ParamT combine(const ParamT &, ModifierT))
408 {
409 return CombineWithValues(in, modifiers.begin(), modifiers.end(), combine);
410 }
411
412 template <typename ParamT, typename ModifiersT, typename ModifierT>
CombineWithValues(const std::vector<ParamT> & in,const ModifiersT & modifiers,ParamT combine (const ParamT &,ModifierT))413 std::vector<ParamT> CombineWithValues(const std::vector<ParamT> &in,
414 const ModifiersT &modifiers,
415 ParamT combine(const ParamT &, ModifierT))
416 {
417 return CombineWithValues(in, std::begin(modifiers), std::end(modifiers), combine);
418 }
419
420 template <typename ParamT, typename FilterFunc>
FilterWithFunc(const std::vector<ParamT> & in,FilterFunc filter)421 std::vector<ParamT> FilterWithFunc(const std::vector<ParamT> &in, FilterFunc filter)
422 {
423 std::vector<ParamT> out;
424 for (const ParamT ¶m : in)
425 {
426 if (filter(param))
427 {
428 out.push_back(param);
429 }
430 }
431 return out;
432 }
433 } // namespace angle
434
435 #define ANGLE_SKIP_TEST_IF(COND) \
436 do \
437 { \
438 if (COND) \
439 { \
440 GTEST_SKIP() << "Test skipped: " #COND "."; \
441 return; \
442 } \
443 } while (0)
444
445 #endif // ANGLE_TEST_INSTANTIATE_H_
446