• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param);
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> &params)
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 &param);
317 
318 // Determines if a config is supported by trying to initialize it. Does
319 // not require SystemInfo.
320 bool IsConfigSupported(const PlatformParameters &param);
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 &paramsIn : 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 &paramsIn : 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 &param : 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