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