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