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