xref: /aosp_15_r20/external/angle/src/tests/test_expectations/GPUTestExpectationsParser.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "GPUTestExpectationsParser.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include <stddef.h>
10*8975f5c5SAndroid Build Coastguard Worker #include <stdint.h>
11*8975f5c5SAndroid Build Coastguard Worker #include <string.h>
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker namespace angle
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker namespace
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker enum LineParserStage
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker     kLineParserBegin = 0,
26*8975f5c5SAndroid Build Coastguard Worker     kLineParserBugID,
27*8975f5c5SAndroid Build Coastguard Worker     kLineParserConfigs,
28*8975f5c5SAndroid Build Coastguard Worker     kLineParserColon,
29*8975f5c5SAndroid Build Coastguard Worker     kLineParserTestName,
30*8975f5c5SAndroid Build Coastguard Worker     kLineParserEqual,
31*8975f5c5SAndroid Build Coastguard Worker     kLineParserExpectations,
32*8975f5c5SAndroid Build Coastguard Worker };
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker enum Token
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker     // os
37*8975f5c5SAndroid Build Coastguard Worker     kConfigWinXP = 0,
38*8975f5c5SAndroid Build Coastguard Worker     kConfigWinVista,
39*8975f5c5SAndroid Build Coastguard Worker     kConfigWin7,
40*8975f5c5SAndroid Build Coastguard Worker     kConfigWin8,
41*8975f5c5SAndroid Build Coastguard Worker     kConfigWin10,
42*8975f5c5SAndroid Build Coastguard Worker     kConfigWin,
43*8975f5c5SAndroid Build Coastguard Worker     kConfigMacLeopard,
44*8975f5c5SAndroid Build Coastguard Worker     kConfigMacSnowLeopard,
45*8975f5c5SAndroid Build Coastguard Worker     kConfigMacLion,
46*8975f5c5SAndroid Build Coastguard Worker     kConfigMacMountainLion,
47*8975f5c5SAndroid Build Coastguard Worker     kConfigMacMavericks,
48*8975f5c5SAndroid Build Coastguard Worker     kConfigMacYosemite,
49*8975f5c5SAndroid Build Coastguard Worker     kConfigMacElCapitan,
50*8975f5c5SAndroid Build Coastguard Worker     kConfigMacSierra,
51*8975f5c5SAndroid Build Coastguard Worker     kConfigMacHighSierra,
52*8975f5c5SAndroid Build Coastguard Worker     kConfigMacMojave,
53*8975f5c5SAndroid Build Coastguard Worker     kConfigMac,
54*8975f5c5SAndroid Build Coastguard Worker     kConfigIOS,
55*8975f5c5SAndroid Build Coastguard Worker     kConfigLinux,
56*8975f5c5SAndroid Build Coastguard Worker     kConfigChromeOS,
57*8975f5c5SAndroid Build Coastguard Worker     kConfigAndroid,
58*8975f5c5SAndroid Build Coastguard Worker     // gpu vendor
59*8975f5c5SAndroid Build Coastguard Worker     kConfigNVIDIA,
60*8975f5c5SAndroid Build Coastguard Worker     kConfigAMD,
61*8975f5c5SAndroid Build Coastguard Worker     kConfigIntel,
62*8975f5c5SAndroid Build Coastguard Worker     kConfigVMWare,
63*8975f5c5SAndroid Build Coastguard Worker     kConfigApple,
64*8975f5c5SAndroid Build Coastguard Worker     // build type
65*8975f5c5SAndroid Build Coastguard Worker     kConfigRelease,
66*8975f5c5SAndroid Build Coastguard Worker     kConfigDebug,
67*8975f5c5SAndroid Build Coastguard Worker     // ANGLE renderer
68*8975f5c5SAndroid Build Coastguard Worker     kConfigD3D9,
69*8975f5c5SAndroid Build Coastguard Worker     kConfigD3D11,
70*8975f5c5SAndroid Build Coastguard Worker     kConfigGLDesktop,
71*8975f5c5SAndroid Build Coastguard Worker     kConfigGLES,
72*8975f5c5SAndroid Build Coastguard Worker     kConfigVulkan,
73*8975f5c5SAndroid Build Coastguard Worker     kConfigSwiftShader,
74*8975f5c5SAndroid Build Coastguard Worker     kConfigMetal,
75*8975f5c5SAndroid Build Coastguard Worker     kConfigWgpu,
76*8975f5c5SAndroid Build Coastguard Worker     // Android devices
77*8975f5c5SAndroid Build Coastguard Worker     kConfigNexus5X,
78*8975f5c5SAndroid Build Coastguard Worker     kConfigPixel2,
79*8975f5c5SAndroid Build Coastguard Worker     kConfigPixel4,
80*8975f5c5SAndroid Build Coastguard Worker     kConfigPixel6,
81*8975f5c5SAndroid Build Coastguard Worker     kConfigPixel7,
82*8975f5c5SAndroid Build Coastguard Worker     kConfigFlipN2,
83*8975f5c5SAndroid Build Coastguard Worker     kConfigMaliG710,
84*8975f5c5SAndroid Build Coastguard Worker     kConfigGalaxyA23,
85*8975f5c5SAndroid Build Coastguard Worker     kConfigGalaxyA34,
86*8975f5c5SAndroid Build Coastguard Worker     kConfigGalaxyA54,
87*8975f5c5SAndroid Build Coastguard Worker     kConfigGalaxyS22,
88*8975f5c5SAndroid Build Coastguard Worker     kConfigGalaxyS23,
89*8975f5c5SAndroid Build Coastguard Worker     kConfigGalaxyS24,
90*8975f5c5SAndroid Build Coastguard Worker     kConfigGalaxyQualcomm,
91*8975f5c5SAndroid Build Coastguard Worker     kConfigFindX6,
92*8975f5c5SAndroid Build Coastguard Worker     kConfigPineapple,
93*8975f5c5SAndroid Build Coastguard Worker     // GPU devices
94*8975f5c5SAndroid Build Coastguard Worker     kConfigNVIDIAQuadroP400,
95*8975f5c5SAndroid Build Coastguard Worker     kConfigNVIDIAGTX1660,
96*8975f5c5SAndroid Build Coastguard Worker     // PreRotation
97*8975f5c5SAndroid Build Coastguard Worker     kConfigPreRotation,
98*8975f5c5SAndroid Build Coastguard Worker     kConfigPreRotation90,
99*8975f5c5SAndroid Build Coastguard Worker     kConfigPreRotation180,
100*8975f5c5SAndroid Build Coastguard Worker     kConfigPreRotation270,
101*8975f5c5SAndroid Build Coastguard Worker     // Sanitizers
102*8975f5c5SAndroid Build Coastguard Worker     kConfigNoSan,
103*8975f5c5SAndroid Build Coastguard Worker     kConfigASan,
104*8975f5c5SAndroid Build Coastguard Worker     kConfigTSan,
105*8975f5c5SAndroid Build Coastguard Worker     kConfigUBSan,
106*8975f5c5SAndroid Build Coastguard Worker     // expectation
107*8975f5c5SAndroid Build Coastguard Worker     kExpectationPass,
108*8975f5c5SAndroid Build Coastguard Worker     kExpectationFail,
109*8975f5c5SAndroid Build Coastguard Worker     kExpectationFlaky,
110*8975f5c5SAndroid Build Coastguard Worker     kExpectationTimeout,
111*8975f5c5SAndroid Build Coastguard Worker     kExpectationSkip,
112*8975f5c5SAndroid Build Coastguard Worker     // separator
113*8975f5c5SAndroid Build Coastguard Worker     kSeparatorColon,
114*8975f5c5SAndroid Build Coastguard Worker     kSeparatorEqual,
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker     kNumberOfExactMatchTokens,
117*8975f5c5SAndroid Build Coastguard Worker 
118*8975f5c5SAndroid Build Coastguard Worker     // others
119*8975f5c5SAndroid Build Coastguard Worker     kTokenComment,
120*8975f5c5SAndroid Build Coastguard Worker     kTokenWord,
121*8975f5c5SAndroid Build Coastguard Worker 
122*8975f5c5SAndroid Build Coastguard Worker     kNumberOfTokens,
123*8975f5c5SAndroid Build Coastguard Worker };
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker enum ErrorType
126*8975f5c5SAndroid Build Coastguard Worker {
127*8975f5c5SAndroid Build Coastguard Worker     kErrorFileIO = 0,
128*8975f5c5SAndroid Build Coastguard Worker     kErrorIllegalEntry,
129*8975f5c5SAndroid Build Coastguard Worker     kErrorInvalidEntry,
130*8975f5c5SAndroid Build Coastguard Worker     kErrorEntryWithExpectationConflicts,
131*8975f5c5SAndroid Build Coastguard Worker     kErrorEntryWithDisallowedExpectation,
132*8975f5c5SAndroid Build Coastguard Worker     kErrorEntriesOverlap,
133*8975f5c5SAndroid Build Coastguard Worker 
134*8975f5c5SAndroid Build Coastguard Worker     kNumberOfErrors,
135*8975f5c5SAndroid Build Coastguard Worker };
136*8975f5c5SAndroid Build Coastguard Worker 
137*8975f5c5SAndroid Build Coastguard Worker struct TokenInfo
138*8975f5c5SAndroid Build Coastguard Worker {
TokenInfoangle::__anonb2f23d3c0111::TokenInfo139*8975f5c5SAndroid Build Coastguard Worker     constexpr TokenInfo()
140*8975f5c5SAndroid Build Coastguard Worker         : name(nullptr),
141*8975f5c5SAndroid Build Coastguard Worker           condition(GPUTestConfig::kConditionNone),
142*8975f5c5SAndroid Build Coastguard Worker           expectation(GPUTestExpectationsParser::kGpuTestPass)
143*8975f5c5SAndroid Build Coastguard Worker     {}
144*8975f5c5SAndroid Build Coastguard Worker 
TokenInfoangle::__anonb2f23d3c0111::TokenInfo145*8975f5c5SAndroid Build Coastguard Worker     constexpr TokenInfo(const char *nameIn,
146*8975f5c5SAndroid Build Coastguard Worker                         GPUTestConfig::Condition conditionIn,
147*8975f5c5SAndroid Build Coastguard Worker                         GPUTestExpectationsParser::GPUTestExpectation expectationIn)
148*8975f5c5SAndroid Build Coastguard Worker         : name(nameIn), condition(conditionIn), expectation(expectationIn)
149*8975f5c5SAndroid Build Coastguard Worker     {}
150*8975f5c5SAndroid Build Coastguard Worker 
TokenInfoangle::__anonb2f23d3c0111::TokenInfo151*8975f5c5SAndroid Build Coastguard Worker     constexpr TokenInfo(const char *nameIn, GPUTestConfig::Condition conditionIn)
152*8975f5c5SAndroid Build Coastguard Worker         : TokenInfo(nameIn, conditionIn, GPUTestExpectationsParser::kGpuTestPass)
153*8975f5c5SAndroid Build Coastguard Worker     {}
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker     const char *name;
156*8975f5c5SAndroid Build Coastguard Worker     GPUTestConfig::Condition condition;
157*8975f5c5SAndroid Build Coastguard Worker     GPUTestExpectationsParser::GPUTestExpectation expectation;
158*8975f5c5SAndroid Build Coastguard Worker };
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker constexpr TokenInfo kTokenData[kNumberOfTokens] = {
161*8975f5c5SAndroid Build Coastguard Worker     {"xp", GPUTestConfig::kConditionWinXP},
162*8975f5c5SAndroid Build Coastguard Worker     {"vista", GPUTestConfig::kConditionWinVista},
163*8975f5c5SAndroid Build Coastguard Worker     {"win7", GPUTestConfig::kConditionWin7},
164*8975f5c5SAndroid Build Coastguard Worker     {"win8", GPUTestConfig::kConditionWin8},
165*8975f5c5SAndroid Build Coastguard Worker     {"win10", GPUTestConfig::kConditionWin10},
166*8975f5c5SAndroid Build Coastguard Worker     {"win", GPUTestConfig::kConditionWin},
167*8975f5c5SAndroid Build Coastguard Worker     {"leopard", GPUTestConfig::kConditionMacLeopard},
168*8975f5c5SAndroid Build Coastguard Worker     {"snowleopard", GPUTestConfig::kConditionMacSnowLeopard},
169*8975f5c5SAndroid Build Coastguard Worker     {"lion", GPUTestConfig::kConditionMacLion},
170*8975f5c5SAndroid Build Coastguard Worker     {"mountainlion", GPUTestConfig::kConditionMacMountainLion},
171*8975f5c5SAndroid Build Coastguard Worker     {"mavericks", GPUTestConfig::kConditionMacMavericks},
172*8975f5c5SAndroid Build Coastguard Worker     {"yosemite", GPUTestConfig::kConditionMacYosemite},
173*8975f5c5SAndroid Build Coastguard Worker     {"elcapitan", GPUTestConfig::kConditionMacElCapitan},
174*8975f5c5SAndroid Build Coastguard Worker     {"sierra", GPUTestConfig::kConditionMacSierra},
175*8975f5c5SAndroid Build Coastguard Worker     {"highsierra", GPUTestConfig::kConditionMacHighSierra},
176*8975f5c5SAndroid Build Coastguard Worker     {"mojave", GPUTestConfig::kConditionMacMojave},
177*8975f5c5SAndroid Build Coastguard Worker     {"mac", GPUTestConfig::kConditionMac},
178*8975f5c5SAndroid Build Coastguard Worker     {"ios", GPUTestConfig::kConditionIOS},
179*8975f5c5SAndroid Build Coastguard Worker     {"linux", GPUTestConfig::kConditionLinux},
180*8975f5c5SAndroid Build Coastguard Worker     {"chromeos",
181*8975f5c5SAndroid Build Coastguard Worker      GPUTestConfig::kConditionNone},  // https://anglebug.com/42262032 CrOS not supported
182*8975f5c5SAndroid Build Coastguard Worker     {"android", GPUTestConfig::kConditionAndroid},
183*8975f5c5SAndroid Build Coastguard Worker     {"nvidia", GPUTestConfig::kConditionNVIDIA},
184*8975f5c5SAndroid Build Coastguard Worker     {"amd", GPUTestConfig::kConditionAMD},
185*8975f5c5SAndroid Build Coastguard Worker     {"intel", GPUTestConfig::kConditionIntel},
186*8975f5c5SAndroid Build Coastguard Worker     {"vmware", GPUTestConfig::kConditionVMWare},
187*8975f5c5SAndroid Build Coastguard Worker     {"apple", GPUTestConfig::kConditionApple},
188*8975f5c5SAndroid Build Coastguard Worker     {"release", GPUTestConfig::kConditionRelease},
189*8975f5c5SAndroid Build Coastguard Worker     {"debug", GPUTestConfig::kConditionDebug},
190*8975f5c5SAndroid Build Coastguard Worker     {"d3d9", GPUTestConfig::kConditionD3D9},
191*8975f5c5SAndroid Build Coastguard Worker     {"d3d11", GPUTestConfig::kConditionD3D11},
192*8975f5c5SAndroid Build Coastguard Worker     {"opengl", GPUTestConfig::kConditionGLDesktop},
193*8975f5c5SAndroid Build Coastguard Worker     {"gles", GPUTestConfig::kConditionGLES},
194*8975f5c5SAndroid Build Coastguard Worker     {"vulkan", GPUTestConfig::kConditionVulkan},
195*8975f5c5SAndroid Build Coastguard Worker     {"swiftshader", GPUTestConfig::kConditionSwiftShader},
196*8975f5c5SAndroid Build Coastguard Worker     {"metal", GPUTestConfig::kConditionMetal},
197*8975f5c5SAndroid Build Coastguard Worker     {"wgpu", GPUTestConfig::kConditionWgpu},
198*8975f5c5SAndroid Build Coastguard Worker     {"nexus5x", GPUTestConfig::kConditionNexus5X},
199*8975f5c5SAndroid Build Coastguard Worker     {"pixel2orxl", GPUTestConfig::kConditionPixel2OrXL},
200*8975f5c5SAndroid Build Coastguard Worker     {"pixel4orxl", GPUTestConfig::kConditionPixel4OrXL},
201*8975f5c5SAndroid Build Coastguard Worker     {"pixel6", GPUTestConfig::kConditionPixel6},
202*8975f5c5SAndroid Build Coastguard Worker     {"pixel7", GPUTestConfig::kConditionPixel7},
203*8975f5c5SAndroid Build Coastguard Worker     {"flipn2", GPUTestConfig::kConditionFlipN2},
204*8975f5c5SAndroid Build Coastguard Worker     {"malig710", GPUTestConfig::kConditionMaliG710},
205*8975f5c5SAndroid Build Coastguard Worker     {"galaxya23", GPUTestConfig::kConditionGalaxyA23},
206*8975f5c5SAndroid Build Coastguard Worker     {"galaxya34", GPUTestConfig::kConditionGalaxyA34},
207*8975f5c5SAndroid Build Coastguard Worker     {"galaxya54", GPUTestConfig::kConditionGalaxyA54},
208*8975f5c5SAndroid Build Coastguard Worker     {"galaxys22", GPUTestConfig::kConditionGalaxyS22},
209*8975f5c5SAndroid Build Coastguard Worker     {"galaxys23", GPUTestConfig::kConditionGalaxyS23},
210*8975f5c5SAndroid Build Coastguard Worker     {"galaxys24", GPUTestConfig::kConditionGalaxyS24},
211*8975f5c5SAndroid Build Coastguard Worker     {"galaxyqualcomm", GPUTestConfig::kConditionGalaxyQualcomm},
212*8975f5c5SAndroid Build Coastguard Worker     {"findx6", GPUTestConfig::kConditionFindX6},
213*8975f5c5SAndroid Build Coastguard Worker     {"pineapple", GPUTestConfig::kConditionPineapple},
214*8975f5c5SAndroid Build Coastguard Worker     {"quadrop400", GPUTestConfig::kConditionNVIDIAQuadroP400},
215*8975f5c5SAndroid Build Coastguard Worker     {"gtx1660", GPUTestConfig::kConditionNVIDIAGTX1660},
216*8975f5c5SAndroid Build Coastguard Worker     {"prerotation", GPUTestConfig::kConditionPreRotation},
217*8975f5c5SAndroid Build Coastguard Worker     {"prerotation90", GPUTestConfig::kConditionPreRotation90},
218*8975f5c5SAndroid Build Coastguard Worker     {"prerotation180", GPUTestConfig::kConditionPreRotation180},
219*8975f5c5SAndroid Build Coastguard Worker     {"prerotation270", GPUTestConfig::kConditionPreRotation270},
220*8975f5c5SAndroid Build Coastguard Worker     {"nosan", GPUTestConfig::kConditionNoSan},
221*8975f5c5SAndroid Build Coastguard Worker     {"asan", GPUTestConfig::kConditionASan},
222*8975f5c5SAndroid Build Coastguard Worker     {"tsan", GPUTestConfig::kConditionTSan},
223*8975f5c5SAndroid Build Coastguard Worker     {"ubsan", GPUTestConfig::kConditionUBSan},
224*8975f5c5SAndroid Build Coastguard Worker     {"pass", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestPass},
225*8975f5c5SAndroid Build Coastguard Worker     {"fail", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestFail},
226*8975f5c5SAndroid Build Coastguard Worker     {"flaky", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestFlaky},
227*8975f5c5SAndroid Build Coastguard Worker     {"timeout", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestTimeout},
228*8975f5c5SAndroid Build Coastguard Worker     {"skip", GPUTestConfig::kConditionNone, GPUTestExpectationsParser::kGpuTestSkip},
229*8975f5c5SAndroid Build Coastguard Worker     {":", GPUTestConfig::kConditionNone},  // kSeparatorColon
230*8975f5c5SAndroid Build Coastguard Worker     {"=", GPUTestConfig::kConditionNone},  // kSeparatorEqual
231*8975f5c5SAndroid Build Coastguard Worker     {},                                    // kNumberOfExactMatchTokens
232*8975f5c5SAndroid Build Coastguard Worker     {},                                    // kTokenComment
233*8975f5c5SAndroid Build Coastguard Worker     {},                                    // kTokenWord
234*8975f5c5SAndroid Build Coastguard Worker };
235*8975f5c5SAndroid Build Coastguard Worker 
236*8975f5c5SAndroid Build Coastguard Worker const char *kErrorMessage[kNumberOfErrors] = {
237*8975f5c5SAndroid Build Coastguard Worker     "file IO failed",
238*8975f5c5SAndroid Build Coastguard Worker     "entry with wrong format",
239*8975f5c5SAndroid Build Coastguard Worker     "entry invalid, likely unimplemented modifiers",
240*8975f5c5SAndroid Build Coastguard Worker     "entry with expectation modifier conflicts",
241*8975f5c5SAndroid Build Coastguard Worker     "entry with unsupported expectation",
242*8975f5c5SAndroid Build Coastguard Worker     "two entries' configs overlap",
243*8975f5c5SAndroid Build Coastguard Worker };
244*8975f5c5SAndroid Build Coastguard Worker 
StartsWithASCII(const std::string & str,const std::string & search,bool caseSensitive)245*8975f5c5SAndroid Build Coastguard Worker inline bool StartsWithASCII(const std::string &str, const std::string &search, bool caseSensitive)
246*8975f5c5SAndroid Build Coastguard Worker {
247*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!caseSensitive);
248*8975f5c5SAndroid Build Coastguard Worker     return str.compare(0, search.length(), search) == 0;
249*8975f5c5SAndroid Build Coastguard Worker }
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker template <class Char>
ToLowerASCII(Char c)252*8975f5c5SAndroid Build Coastguard Worker inline Char ToLowerASCII(Char c)
253*8975f5c5SAndroid Build Coastguard Worker {
254*8975f5c5SAndroid Build Coastguard Worker     return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
255*8975f5c5SAndroid Build Coastguard Worker }
256*8975f5c5SAndroid Build Coastguard Worker 
257*8975f5c5SAndroid Build Coastguard Worker template <typename Iter>
DoLowerCaseEqualsASCII(Iter a_begin,Iter a_end,const char * b)258*8975f5c5SAndroid Build Coastguard Worker inline bool DoLowerCaseEqualsASCII(Iter a_begin, Iter a_end, const char *b)
259*8975f5c5SAndroid Build Coastguard Worker {
260*8975f5c5SAndroid Build Coastguard Worker     for (Iter it = a_begin; it != a_end; ++it, ++b)
261*8975f5c5SAndroid Build Coastguard Worker     {
262*8975f5c5SAndroid Build Coastguard Worker         if (!*b || ToLowerASCII(*it) != *b)
263*8975f5c5SAndroid Build Coastguard Worker             return false;
264*8975f5c5SAndroid Build Coastguard Worker     }
265*8975f5c5SAndroid Build Coastguard Worker     return *b == 0;
266*8975f5c5SAndroid Build Coastguard Worker }
267*8975f5c5SAndroid Build Coastguard Worker 
LowerCaseEqualsASCII(const std::string & a,const char * b)268*8975f5c5SAndroid Build Coastguard Worker inline bool LowerCaseEqualsASCII(const std::string &a, const char *b)
269*8975f5c5SAndroid Build Coastguard Worker {
270*8975f5c5SAndroid Build Coastguard Worker     return DoLowerCaseEqualsASCII(a.begin(), a.end(), b);
271*8975f5c5SAndroid Build Coastguard Worker }
272*8975f5c5SAndroid Build Coastguard Worker 
ParseToken(const std::string & word)273*8975f5c5SAndroid Build Coastguard Worker inline Token ParseToken(const std::string &word)
274*8975f5c5SAndroid Build Coastguard Worker {
275*8975f5c5SAndroid Build Coastguard Worker     if (StartsWithASCII(word, "//", false))
276*8975f5c5SAndroid Build Coastguard Worker         return kTokenComment;
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker     for (int32_t i = 0; i < kNumberOfExactMatchTokens; ++i)
279*8975f5c5SAndroid Build Coastguard Worker     {
280*8975f5c5SAndroid Build Coastguard Worker         if (LowerCaseEqualsASCII(word, kTokenData[i].name))
281*8975f5c5SAndroid Build Coastguard Worker             return static_cast<Token>(i);
282*8975f5c5SAndroid Build Coastguard Worker     }
283*8975f5c5SAndroid Build Coastguard Worker     return kTokenWord;
284*8975f5c5SAndroid Build Coastguard Worker }
285*8975f5c5SAndroid Build Coastguard Worker 
ConditionArrayIsSubset(const GPUTestConfig::ConditionArray & subset,const GPUTestConfig::ConditionArray & superset)286*8975f5c5SAndroid Build Coastguard Worker bool ConditionArrayIsSubset(const GPUTestConfig::ConditionArray &subset,
287*8975f5c5SAndroid Build Coastguard Worker                             const GPUTestConfig::ConditionArray &superset)
288*8975f5c5SAndroid Build Coastguard Worker {
289*8975f5c5SAndroid Build Coastguard Worker     for (size_t subsetCondition : subset)
290*8975f5c5SAndroid Build Coastguard Worker     {
291*8975f5c5SAndroid Build Coastguard Worker         bool foundCondition = false;
292*8975f5c5SAndroid Build Coastguard Worker         for (size_t supersetCondition : superset)
293*8975f5c5SAndroid Build Coastguard Worker         {
294*8975f5c5SAndroid Build Coastguard Worker             if (subsetCondition == supersetCondition)
295*8975f5c5SAndroid Build Coastguard Worker             {
296*8975f5c5SAndroid Build Coastguard Worker                 foundCondition = true;
297*8975f5c5SAndroid Build Coastguard Worker                 break;
298*8975f5c5SAndroid Build Coastguard Worker             }
299*8975f5c5SAndroid Build Coastguard Worker         }
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker         if (!foundCondition)
302*8975f5c5SAndroid Build Coastguard Worker         {
303*8975f5c5SAndroid Build Coastguard Worker             return false;
304*8975f5c5SAndroid Build Coastguard Worker         }
305*8975f5c5SAndroid Build Coastguard Worker     }
306*8975f5c5SAndroid Build Coastguard Worker 
307*8975f5c5SAndroid Build Coastguard Worker     return true;
308*8975f5c5SAndroid Build Coastguard Worker }
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker // If one array is completely contained within the other, then we say the conditions overlap.
ConditionsOverlap(const GPUTestConfig::ConditionArray & conditionsI,const GPUTestConfig::ConditionArray & conditionsJ)311*8975f5c5SAndroid Build Coastguard Worker bool ConditionsOverlap(const GPUTestConfig::ConditionArray &conditionsI,
312*8975f5c5SAndroid Build Coastguard Worker                        const GPUTestConfig::ConditionArray &conditionsJ)
313*8975f5c5SAndroid Build Coastguard Worker {
314*8975f5c5SAndroid Build Coastguard Worker     return ConditionArrayIsSubset(conditionsI, conditionsJ) ||
315*8975f5c5SAndroid Build Coastguard Worker            ConditionArrayIsSubset(conditionsJ, conditionsI);
316*8975f5c5SAndroid Build Coastguard Worker }
317*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
318*8975f5c5SAndroid Build Coastguard Worker 
GetConditionName(uint32_t condition)319*8975f5c5SAndroid Build Coastguard Worker const char *GetConditionName(uint32_t condition)
320*8975f5c5SAndroid Build Coastguard Worker {
321*8975f5c5SAndroid Build Coastguard Worker     if (condition == GPUTestConfig::kConditionNone)
322*8975f5c5SAndroid Build Coastguard Worker     {
323*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
324*8975f5c5SAndroid Build Coastguard Worker     }
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker     for (const TokenInfo &info : kTokenData)
327*8975f5c5SAndroid Build Coastguard Worker     {
328*8975f5c5SAndroid Build Coastguard Worker         if (info.condition == condition)
329*8975f5c5SAndroid Build Coastguard Worker         {
330*8975f5c5SAndroid Build Coastguard Worker             // kConditionNone is used to tag tokens that aren't conditions, but this case has been
331*8975f5c5SAndroid Build Coastguard Worker             // handled above.
332*8975f5c5SAndroid Build Coastguard Worker             ASSERT(info.condition != GPUTestConfig::kConditionNone);
333*8975f5c5SAndroid Build Coastguard Worker             return info.name;
334*8975f5c5SAndroid Build Coastguard Worker         }
335*8975f5c5SAndroid Build Coastguard Worker     }
336*8975f5c5SAndroid Build Coastguard Worker 
337*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker 
GPUTestExpectationsParser()340*8975f5c5SAndroid Build Coastguard Worker GPUTestExpectationsParser::GPUTestExpectationsParser()
341*8975f5c5SAndroid Build Coastguard Worker     : mExpectationsAllowMask(
342*8975f5c5SAndroid Build Coastguard Worker           GPUTestExpectationsParser::kGpuTestPass | GPUTestExpectationsParser::kGpuTestFail |
343*8975f5c5SAndroid Build Coastguard Worker           GPUTestExpectationsParser::kGpuTestFlaky | GPUTestExpectationsParser::kGpuTestTimeout |
344*8975f5c5SAndroid Build Coastguard Worker           GPUTestExpectationsParser::kGpuTestSkip)
345*8975f5c5SAndroid Build Coastguard Worker {
346*8975f5c5SAndroid Build Coastguard Worker     // Some initial checks.
347*8975f5c5SAndroid Build Coastguard Worker     ASSERT((static_cast<unsigned int>(kNumberOfTokens)) ==
348*8975f5c5SAndroid Build Coastguard Worker            (sizeof(kTokenData) / sizeof(kTokenData[0])));
349*8975f5c5SAndroid Build Coastguard Worker     ASSERT((static_cast<unsigned int>(kNumberOfErrors)) ==
350*8975f5c5SAndroid Build Coastguard Worker            (sizeof(kErrorMessage) / sizeof(kErrorMessage[0])));
351*8975f5c5SAndroid Build Coastguard Worker }
352*8975f5c5SAndroid Build Coastguard Worker 
353*8975f5c5SAndroid Build Coastguard Worker GPUTestExpectationsParser::~GPUTestExpectationsParser() = default;
354*8975f5c5SAndroid Build Coastguard Worker 
loadTestExpectationsImpl(const GPUTestConfig * config,const std::string & data)355*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::loadTestExpectationsImpl(const GPUTestConfig *config,
356*8975f5c5SAndroid Build Coastguard Worker                                                          const std::string &data)
357*8975f5c5SAndroid Build Coastguard Worker {
358*8975f5c5SAndroid Build Coastguard Worker     mEntries.clear();
359*8975f5c5SAndroid Build Coastguard Worker     mErrorMessages.clear();
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> lines = SplitString(data, "\n", TRIM_WHITESPACE, SPLIT_WANT_ALL);
362*8975f5c5SAndroid Build Coastguard Worker     bool rt                        = true;
363*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < lines.size(); ++i)
364*8975f5c5SAndroid Build Coastguard Worker     {
365*8975f5c5SAndroid Build Coastguard Worker         if (!parseLine(config, lines[i], i + 1))
366*8975f5c5SAndroid Build Coastguard Worker             rt = false;
367*8975f5c5SAndroid Build Coastguard Worker     }
368*8975f5c5SAndroid Build Coastguard Worker     if (detectConflictsBetweenEntries())
369*8975f5c5SAndroid Build Coastguard Worker     {
370*8975f5c5SAndroid Build Coastguard Worker         mEntries.clear();
371*8975f5c5SAndroid Build Coastguard Worker         rt = false;
372*8975f5c5SAndroid Build Coastguard Worker     }
373*8975f5c5SAndroid Build Coastguard Worker 
374*8975f5c5SAndroid Build Coastguard Worker     return rt;
375*8975f5c5SAndroid Build Coastguard Worker }
376*8975f5c5SAndroid Build Coastguard Worker 
loadTestExpectations(const GPUTestConfig & config,const std::string & data)377*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::loadTestExpectations(const GPUTestConfig &config,
378*8975f5c5SAndroid Build Coastguard Worker                                                      const std::string &data)
379*8975f5c5SAndroid Build Coastguard Worker {
380*8975f5c5SAndroid Build Coastguard Worker     return loadTestExpectationsImpl(&config, data);
381*8975f5c5SAndroid Build Coastguard Worker }
382*8975f5c5SAndroid Build Coastguard Worker 
loadAllTestExpectations(const std::string & data)383*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::loadAllTestExpectations(const std::string &data)
384*8975f5c5SAndroid Build Coastguard Worker {
385*8975f5c5SAndroid Build Coastguard Worker     return loadTestExpectationsImpl(nullptr, data);
386*8975f5c5SAndroid Build Coastguard Worker }
387*8975f5c5SAndroid Build Coastguard Worker 
loadTestExpectationsFromFileImpl(const GPUTestConfig * config,const std::string & path)388*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::loadTestExpectationsFromFileImpl(const GPUTestConfig *config,
389*8975f5c5SAndroid Build Coastguard Worker                                                                  const std::string &path)
390*8975f5c5SAndroid Build Coastguard Worker {
391*8975f5c5SAndroid Build Coastguard Worker     mEntries.clear();
392*8975f5c5SAndroid Build Coastguard Worker     mErrorMessages.clear();
393*8975f5c5SAndroid Build Coastguard Worker 
394*8975f5c5SAndroid Build Coastguard Worker     std::string data;
395*8975f5c5SAndroid Build Coastguard Worker     if (!ReadFileToString(path, &data))
396*8975f5c5SAndroid Build Coastguard Worker     {
397*8975f5c5SAndroid Build Coastguard Worker         mErrorMessages.push_back(kErrorMessage[kErrorFileIO]);
398*8975f5c5SAndroid Build Coastguard Worker         return false;
399*8975f5c5SAndroid Build Coastguard Worker     }
400*8975f5c5SAndroid Build Coastguard Worker     return loadTestExpectationsImpl(config, data);
401*8975f5c5SAndroid Build Coastguard Worker }
402*8975f5c5SAndroid Build Coastguard Worker 
loadTestExpectationsFromFile(const GPUTestConfig & config,const std::string & path)403*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::loadTestExpectationsFromFile(const GPUTestConfig &config,
404*8975f5c5SAndroid Build Coastguard Worker                                                              const std::string &path)
405*8975f5c5SAndroid Build Coastguard Worker {
406*8975f5c5SAndroid Build Coastguard Worker     return loadTestExpectationsFromFileImpl(&config, path);
407*8975f5c5SAndroid Build Coastguard Worker }
408*8975f5c5SAndroid Build Coastguard Worker 
loadAllTestExpectationsFromFile(const std::string & path)409*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::loadAllTestExpectationsFromFile(const std::string &path)
410*8975f5c5SAndroid Build Coastguard Worker {
411*8975f5c5SAndroid Build Coastguard Worker     return loadTestExpectationsFromFileImpl(nullptr, path);
412*8975f5c5SAndroid Build Coastguard Worker }
413*8975f5c5SAndroid Build Coastguard Worker 
getTestExpectationImpl(const GPUTestConfig * config,const std::string & testName)414*8975f5c5SAndroid Build Coastguard Worker int32_t GPUTestExpectationsParser::getTestExpectationImpl(const GPUTestConfig *config,
415*8975f5c5SAndroid Build Coastguard Worker                                                           const std::string &testName)
416*8975f5c5SAndroid Build Coastguard Worker {
417*8975f5c5SAndroid Build Coastguard Worker     for (GPUTestExpectationEntry &entry : mEntries)
418*8975f5c5SAndroid Build Coastguard Worker     {
419*8975f5c5SAndroid Build Coastguard Worker         if (NamesMatchWithWildcard(entry.testName.c_str(), testName.c_str()))
420*8975f5c5SAndroid Build Coastguard Worker         {
421*8975f5c5SAndroid Build Coastguard Worker             // Filter by condition first.
422*8975f5c5SAndroid Build Coastguard Worker             bool satisfiesConditions = true;
423*8975f5c5SAndroid Build Coastguard Worker             if (config)
424*8975f5c5SAndroid Build Coastguard Worker             {
425*8975f5c5SAndroid Build Coastguard Worker                 for (size_t condition : entry.conditions)
426*8975f5c5SAndroid Build Coastguard Worker                 {
427*8975f5c5SAndroid Build Coastguard Worker                     if (!config->getConditions()[condition])
428*8975f5c5SAndroid Build Coastguard Worker                     {
429*8975f5c5SAndroid Build Coastguard Worker                         satisfiesConditions = false;
430*8975f5c5SAndroid Build Coastguard Worker                         break;
431*8975f5c5SAndroid Build Coastguard Worker                     }
432*8975f5c5SAndroid Build Coastguard Worker                 }
433*8975f5c5SAndroid Build Coastguard Worker             }
434*8975f5c5SAndroid Build Coastguard Worker 
435*8975f5c5SAndroid Build Coastguard Worker             // Use the first matching expectation in the file as the matching expression.
436*8975f5c5SAndroid Build Coastguard Worker             if (satisfiesConditions)
437*8975f5c5SAndroid Build Coastguard Worker             {
438*8975f5c5SAndroid Build Coastguard Worker                 entry.used = true;
439*8975f5c5SAndroid Build Coastguard Worker                 return entry.testExpectation;
440*8975f5c5SAndroid Build Coastguard Worker             }
441*8975f5c5SAndroid Build Coastguard Worker         }
442*8975f5c5SAndroid Build Coastguard Worker     }
443*8975f5c5SAndroid Build Coastguard Worker     return kGpuTestPass;
444*8975f5c5SAndroid Build Coastguard Worker }
445*8975f5c5SAndroid Build Coastguard Worker 
getTestExpectation(const std::string & testName)446*8975f5c5SAndroid Build Coastguard Worker int32_t GPUTestExpectationsParser::getTestExpectation(const std::string &testName)
447*8975f5c5SAndroid Build Coastguard Worker {
448*8975f5c5SAndroid Build Coastguard Worker     return getTestExpectationImpl(nullptr, testName);
449*8975f5c5SAndroid Build Coastguard Worker }
450*8975f5c5SAndroid Build Coastguard Worker 
getTestExpectationWithConfig(const GPUTestConfig & config,const std::string & testName)451*8975f5c5SAndroid Build Coastguard Worker int32_t GPUTestExpectationsParser::getTestExpectationWithConfig(const GPUTestConfig &config,
452*8975f5c5SAndroid Build Coastguard Worker                                                                 const std::string &testName)
453*8975f5c5SAndroid Build Coastguard Worker {
454*8975f5c5SAndroid Build Coastguard Worker     return getTestExpectationImpl(&config, testName);
455*8975f5c5SAndroid Build Coastguard Worker }
456*8975f5c5SAndroid Build Coastguard Worker 
getErrorMessages() const457*8975f5c5SAndroid Build Coastguard Worker const std::vector<std::string> &GPUTestExpectationsParser::getErrorMessages() const
458*8975f5c5SAndroid Build Coastguard Worker {
459*8975f5c5SAndroid Build Coastguard Worker     return mErrorMessages;
460*8975f5c5SAndroid Build Coastguard Worker }
461*8975f5c5SAndroid Build Coastguard Worker 
getUnusedExpectationsMessages() const462*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> GPUTestExpectationsParser::getUnusedExpectationsMessages() const
463*8975f5c5SAndroid Build Coastguard Worker {
464*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> messages;
465*8975f5c5SAndroid Build Coastguard Worker     std::vector<GPUTestExpectationsParser::GPUTestExpectationEntry> unusedExpectations =
466*8975f5c5SAndroid Build Coastguard Worker         getUnusedExpectations();
467*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < unusedExpectations.size(); ++i)
468*8975f5c5SAndroid Build Coastguard Worker     {
469*8975f5c5SAndroid Build Coastguard Worker         std::string message =
470*8975f5c5SAndroid Build Coastguard Worker             "Line " + ToString(unusedExpectations[i].lineNumber) + ": expectation was unused.";
471*8975f5c5SAndroid Build Coastguard Worker         messages.push_back(message);
472*8975f5c5SAndroid Build Coastguard Worker     }
473*8975f5c5SAndroid Build Coastguard Worker     return messages;
474*8975f5c5SAndroid Build Coastguard Worker }
475*8975f5c5SAndroid Build Coastguard Worker 
parseLine(const GPUTestConfig * config,const std::string & lineData,size_t lineNumber)476*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::parseLine(const GPUTestConfig *config,
477*8975f5c5SAndroid Build Coastguard Worker                                           const std::string &lineData,
478*8975f5c5SAndroid Build Coastguard Worker                                           size_t lineNumber)
479*8975f5c5SAndroid Build Coastguard Worker {
480*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> tokens =
481*8975f5c5SAndroid Build Coastguard Worker         SplitString(lineData, kWhitespaceASCII, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
482*8975f5c5SAndroid Build Coastguard Worker     int32_t stage = kLineParserBegin;
483*8975f5c5SAndroid Build Coastguard Worker     GPUTestExpectationEntry entry;
484*8975f5c5SAndroid Build Coastguard Worker     entry.lineNumber = lineNumber;
485*8975f5c5SAndroid Build Coastguard Worker     entry.used       = false;
486*8975f5c5SAndroid Build Coastguard Worker     bool skipLine    = false;
487*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < tokens.size() && !skipLine; ++i)
488*8975f5c5SAndroid Build Coastguard Worker     {
489*8975f5c5SAndroid Build Coastguard Worker         Token token = ParseToken(tokens[i]);
490*8975f5c5SAndroid Build Coastguard Worker         switch (token)
491*8975f5c5SAndroid Build Coastguard Worker         {
492*8975f5c5SAndroid Build Coastguard Worker             case kTokenComment:
493*8975f5c5SAndroid Build Coastguard Worker                 skipLine = true;
494*8975f5c5SAndroid Build Coastguard Worker                 break;
495*8975f5c5SAndroid Build Coastguard Worker             case kConfigWinXP:
496*8975f5c5SAndroid Build Coastguard Worker             case kConfigWinVista:
497*8975f5c5SAndroid Build Coastguard Worker             case kConfigWin7:
498*8975f5c5SAndroid Build Coastguard Worker             case kConfigWin8:
499*8975f5c5SAndroid Build Coastguard Worker             case kConfigWin10:
500*8975f5c5SAndroid Build Coastguard Worker             case kConfigWin:
501*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacLeopard:
502*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacSnowLeopard:
503*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacLion:
504*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacMountainLion:
505*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacMavericks:
506*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacYosemite:
507*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacElCapitan:
508*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacSierra:
509*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacHighSierra:
510*8975f5c5SAndroid Build Coastguard Worker             case kConfigMacMojave:
511*8975f5c5SAndroid Build Coastguard Worker             case kConfigMac:
512*8975f5c5SAndroid Build Coastguard Worker             case kConfigIOS:
513*8975f5c5SAndroid Build Coastguard Worker             case kConfigLinux:
514*8975f5c5SAndroid Build Coastguard Worker             case kConfigChromeOS:
515*8975f5c5SAndroid Build Coastguard Worker             case kConfigAndroid:
516*8975f5c5SAndroid Build Coastguard Worker             case kConfigNVIDIA:
517*8975f5c5SAndroid Build Coastguard Worker             case kConfigAMD:
518*8975f5c5SAndroid Build Coastguard Worker             case kConfigIntel:
519*8975f5c5SAndroid Build Coastguard Worker             case kConfigVMWare:
520*8975f5c5SAndroid Build Coastguard Worker             case kConfigApple:
521*8975f5c5SAndroid Build Coastguard Worker             case kConfigRelease:
522*8975f5c5SAndroid Build Coastguard Worker             case kConfigDebug:
523*8975f5c5SAndroid Build Coastguard Worker             case kConfigD3D9:
524*8975f5c5SAndroid Build Coastguard Worker             case kConfigD3D11:
525*8975f5c5SAndroid Build Coastguard Worker             case kConfigGLDesktop:
526*8975f5c5SAndroid Build Coastguard Worker             case kConfigGLES:
527*8975f5c5SAndroid Build Coastguard Worker             case kConfigVulkan:
528*8975f5c5SAndroid Build Coastguard Worker             case kConfigSwiftShader:
529*8975f5c5SAndroid Build Coastguard Worker             case kConfigMetal:
530*8975f5c5SAndroid Build Coastguard Worker             case kConfigWgpu:
531*8975f5c5SAndroid Build Coastguard Worker             case kConfigNexus5X:
532*8975f5c5SAndroid Build Coastguard Worker             case kConfigPixel2:
533*8975f5c5SAndroid Build Coastguard Worker             case kConfigPixel4:
534*8975f5c5SAndroid Build Coastguard Worker             case kConfigPixel6:
535*8975f5c5SAndroid Build Coastguard Worker             case kConfigPixel7:
536*8975f5c5SAndroid Build Coastguard Worker             case kConfigFlipN2:
537*8975f5c5SAndroid Build Coastguard Worker             case kConfigMaliG710:
538*8975f5c5SAndroid Build Coastguard Worker             case kConfigGalaxyA23:
539*8975f5c5SAndroid Build Coastguard Worker             case kConfigGalaxyA34:
540*8975f5c5SAndroid Build Coastguard Worker             case kConfigGalaxyA54:
541*8975f5c5SAndroid Build Coastguard Worker             case kConfigGalaxyS22:
542*8975f5c5SAndroid Build Coastguard Worker             case kConfigGalaxyS23:
543*8975f5c5SAndroid Build Coastguard Worker             case kConfigGalaxyS24:
544*8975f5c5SAndroid Build Coastguard Worker             case kConfigGalaxyQualcomm:
545*8975f5c5SAndroid Build Coastguard Worker             case kConfigFindX6:
546*8975f5c5SAndroid Build Coastguard Worker             case kConfigPineapple:
547*8975f5c5SAndroid Build Coastguard Worker             case kConfigNVIDIAQuadroP400:
548*8975f5c5SAndroid Build Coastguard Worker             case kConfigNVIDIAGTX1660:
549*8975f5c5SAndroid Build Coastguard Worker             case kConfigPreRotation:
550*8975f5c5SAndroid Build Coastguard Worker             case kConfigPreRotation90:
551*8975f5c5SAndroid Build Coastguard Worker             case kConfigPreRotation180:
552*8975f5c5SAndroid Build Coastguard Worker             case kConfigPreRotation270:
553*8975f5c5SAndroid Build Coastguard Worker             case kConfigNoSan:
554*8975f5c5SAndroid Build Coastguard Worker             case kConfigASan:
555*8975f5c5SAndroid Build Coastguard Worker             case kConfigTSan:
556*8975f5c5SAndroid Build Coastguard Worker             case kConfigUBSan:
557*8975f5c5SAndroid Build Coastguard Worker                 // MODIFIERS, check each condition and add accordingly.
558*8975f5c5SAndroid Build Coastguard Worker                 if (stage != kLineParserConfigs && stage != kLineParserBugID)
559*8975f5c5SAndroid Build Coastguard Worker                 {
560*8975f5c5SAndroid Build Coastguard Worker                     pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
561*8975f5c5SAndroid Build Coastguard Worker                     return false;
562*8975f5c5SAndroid Build Coastguard Worker                 }
563*8975f5c5SAndroid Build Coastguard Worker                 {
564*8975f5c5SAndroid Build Coastguard Worker                     bool err = false;
565*8975f5c5SAndroid Build Coastguard Worker                     if (config)
566*8975f5c5SAndroid Build Coastguard Worker                     {
567*8975f5c5SAndroid Build Coastguard Worker                         if (!checkTokenCondition(*config, err, token, lineNumber))
568*8975f5c5SAndroid Build Coastguard Worker                         {
569*8975f5c5SAndroid Build Coastguard Worker                             skipLine = true;  // Move to the next line without adding this one.
570*8975f5c5SAndroid Build Coastguard Worker                         }
571*8975f5c5SAndroid Build Coastguard Worker                     }
572*8975f5c5SAndroid Build Coastguard Worker                     else
573*8975f5c5SAndroid Build Coastguard Worker                     {
574*8975f5c5SAndroid Build Coastguard Worker                         // Store the conditions for later comparison if we don't have a config.
575*8975f5c5SAndroid Build Coastguard Worker                         entry.conditions[kTokenData[token].condition] = true;
576*8975f5c5SAndroid Build Coastguard Worker                     }
577*8975f5c5SAndroid Build Coastguard Worker                     if (err)
578*8975f5c5SAndroid Build Coastguard Worker                     {
579*8975f5c5SAndroid Build Coastguard Worker                         return false;
580*8975f5c5SAndroid Build Coastguard Worker                     }
581*8975f5c5SAndroid Build Coastguard Worker                 }
582*8975f5c5SAndroid Build Coastguard Worker                 if (stage == kLineParserBugID)
583*8975f5c5SAndroid Build Coastguard Worker                 {
584*8975f5c5SAndroid Build Coastguard Worker                     stage++;
585*8975f5c5SAndroid Build Coastguard Worker                 }
586*8975f5c5SAndroid Build Coastguard Worker                 break;
587*8975f5c5SAndroid Build Coastguard Worker             case kSeparatorColon:
588*8975f5c5SAndroid Build Coastguard Worker                 // :
589*8975f5c5SAndroid Build Coastguard Worker                 // If there are no modifiers, move straight to separator colon
590*8975f5c5SAndroid Build Coastguard Worker                 if (stage == kLineParserBugID)
591*8975f5c5SAndroid Build Coastguard Worker                 {
592*8975f5c5SAndroid Build Coastguard Worker                     stage++;
593*8975f5c5SAndroid Build Coastguard Worker                 }
594*8975f5c5SAndroid Build Coastguard Worker                 if (stage != kLineParserConfigs)
595*8975f5c5SAndroid Build Coastguard Worker                 {
596*8975f5c5SAndroid Build Coastguard Worker                     pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
597*8975f5c5SAndroid Build Coastguard Worker                     return false;
598*8975f5c5SAndroid Build Coastguard Worker                 }
599*8975f5c5SAndroid Build Coastguard Worker                 stage++;
600*8975f5c5SAndroid Build Coastguard Worker                 break;
601*8975f5c5SAndroid Build Coastguard Worker             case kSeparatorEqual:
602*8975f5c5SAndroid Build Coastguard Worker                 // =
603*8975f5c5SAndroid Build Coastguard Worker                 if (stage != kLineParserTestName)
604*8975f5c5SAndroid Build Coastguard Worker                 {
605*8975f5c5SAndroid Build Coastguard Worker                     pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
606*8975f5c5SAndroid Build Coastguard Worker                     return false;
607*8975f5c5SAndroid Build Coastguard Worker                 }
608*8975f5c5SAndroid Build Coastguard Worker                 stage++;
609*8975f5c5SAndroid Build Coastguard Worker                 break;
610*8975f5c5SAndroid Build Coastguard Worker             case kTokenWord:
611*8975f5c5SAndroid Build Coastguard Worker                 // BUG_ID or TEST_NAME
612*8975f5c5SAndroid Build Coastguard Worker                 if (stage == kLineParserBegin)
613*8975f5c5SAndroid Build Coastguard Worker                 {
614*8975f5c5SAndroid Build Coastguard Worker                     // Bug ID is not used for anything; ignore it.
615*8975f5c5SAndroid Build Coastguard Worker                 }
616*8975f5c5SAndroid Build Coastguard Worker                 else if (stage == kLineParserColon)
617*8975f5c5SAndroid Build Coastguard Worker                 {
618*8975f5c5SAndroid Build Coastguard Worker                     entry.testName = tokens[i];
619*8975f5c5SAndroid Build Coastguard Worker                 }
620*8975f5c5SAndroid Build Coastguard Worker                 else
621*8975f5c5SAndroid Build Coastguard Worker                 {
622*8975f5c5SAndroid Build Coastguard Worker                     pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
623*8975f5c5SAndroid Build Coastguard Worker                     return false;
624*8975f5c5SAndroid Build Coastguard Worker                 }
625*8975f5c5SAndroid Build Coastguard Worker                 stage++;
626*8975f5c5SAndroid Build Coastguard Worker                 break;
627*8975f5c5SAndroid Build Coastguard Worker             case kExpectationPass:
628*8975f5c5SAndroid Build Coastguard Worker             case kExpectationFail:
629*8975f5c5SAndroid Build Coastguard Worker             case kExpectationFlaky:
630*8975f5c5SAndroid Build Coastguard Worker             case kExpectationTimeout:
631*8975f5c5SAndroid Build Coastguard Worker             case kExpectationSkip:
632*8975f5c5SAndroid Build Coastguard Worker                 // TEST_EXPECTATIONS
633*8975f5c5SAndroid Build Coastguard Worker                 if (stage != kLineParserEqual && stage != kLineParserExpectations)
634*8975f5c5SAndroid Build Coastguard Worker                 {
635*8975f5c5SAndroid Build Coastguard Worker                     pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
636*8975f5c5SAndroid Build Coastguard Worker                     return false;
637*8975f5c5SAndroid Build Coastguard Worker                 }
638*8975f5c5SAndroid Build Coastguard Worker                 if (entry.testExpectation != 0)
639*8975f5c5SAndroid Build Coastguard Worker                 {
640*8975f5c5SAndroid Build Coastguard Worker                     pushErrorMessage(kErrorMessage[kErrorEntryWithExpectationConflicts],
641*8975f5c5SAndroid Build Coastguard Worker                                      lineNumber);
642*8975f5c5SAndroid Build Coastguard Worker                     return false;
643*8975f5c5SAndroid Build Coastguard Worker                 }
644*8975f5c5SAndroid Build Coastguard Worker                 if ((mExpectationsAllowMask & kTokenData[token].expectation) == 0)
645*8975f5c5SAndroid Build Coastguard Worker                 {
646*8975f5c5SAndroid Build Coastguard Worker                     pushErrorMessage(kErrorMessage[kErrorEntryWithDisallowedExpectation],
647*8975f5c5SAndroid Build Coastguard Worker                                      lineNumber);
648*8975f5c5SAndroid Build Coastguard Worker                     return false;
649*8975f5c5SAndroid Build Coastguard Worker                 }
650*8975f5c5SAndroid Build Coastguard Worker                 entry.testExpectation = kTokenData[token].expectation;
651*8975f5c5SAndroid Build Coastguard Worker                 if (stage == kLineParserEqual)
652*8975f5c5SAndroid Build Coastguard Worker                     stage++;
653*8975f5c5SAndroid Build Coastguard Worker                 break;
654*8975f5c5SAndroid Build Coastguard Worker             default:
655*8975f5c5SAndroid Build Coastguard Worker                 ASSERT(false);
656*8975f5c5SAndroid Build Coastguard Worker                 break;
657*8975f5c5SAndroid Build Coastguard Worker         }
658*8975f5c5SAndroid Build Coastguard Worker     }
659*8975f5c5SAndroid Build Coastguard Worker     if (stage == kLineParserBegin || skipLine)
660*8975f5c5SAndroid Build Coastguard Worker     {
661*8975f5c5SAndroid Build Coastguard Worker         // The whole line is empty or all comments, or has been skipped to to a condition token.
662*8975f5c5SAndroid Build Coastguard Worker         return true;
663*8975f5c5SAndroid Build Coastguard Worker     }
664*8975f5c5SAndroid Build Coastguard Worker     if (stage == kLineParserExpectations)
665*8975f5c5SAndroid Build Coastguard Worker     {
666*8975f5c5SAndroid Build Coastguard Worker         mEntries.push_back(entry);
667*8975f5c5SAndroid Build Coastguard Worker         return true;
668*8975f5c5SAndroid Build Coastguard Worker     }
669*8975f5c5SAndroid Build Coastguard Worker     pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
670*8975f5c5SAndroid Build Coastguard Worker     return false;
671*8975f5c5SAndroid Build Coastguard Worker }
672*8975f5c5SAndroid Build Coastguard Worker 
checkTokenCondition(const GPUTestConfig & config,bool & err,int32_t token,size_t lineNumber)673*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::checkTokenCondition(const GPUTestConfig &config,
674*8975f5c5SAndroid Build Coastguard Worker                                                     bool &err,
675*8975f5c5SAndroid Build Coastguard Worker                                                     int32_t token,
676*8975f5c5SAndroid Build Coastguard Worker                                                     size_t lineNumber)
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker     if (token >= kNumberOfTokens)
679*8975f5c5SAndroid Build Coastguard Worker     {
680*8975f5c5SAndroid Build Coastguard Worker         pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
681*8975f5c5SAndroid Build Coastguard Worker         err = true;
682*8975f5c5SAndroid Build Coastguard Worker         return false;
683*8975f5c5SAndroid Build Coastguard Worker     }
684*8975f5c5SAndroid Build Coastguard Worker 
685*8975f5c5SAndroid Build Coastguard Worker     if (kTokenData[token].condition == GPUTestConfig::kConditionNone ||
686*8975f5c5SAndroid Build Coastguard Worker         kTokenData[token].condition >= GPUTestConfig::kNumberOfConditions)
687*8975f5c5SAndroid Build Coastguard Worker     {
688*8975f5c5SAndroid Build Coastguard Worker         pushErrorMessage(kErrorMessage[kErrorInvalidEntry], lineNumber);
689*8975f5c5SAndroid Build Coastguard Worker         // error on any unsupported conditions
690*8975f5c5SAndroid Build Coastguard Worker         err = true;
691*8975f5c5SAndroid Build Coastguard Worker         return false;
692*8975f5c5SAndroid Build Coastguard Worker     }
693*8975f5c5SAndroid Build Coastguard Worker     err = false;
694*8975f5c5SAndroid Build Coastguard Worker     return config.getConditions()[kTokenData[token].condition];
695*8975f5c5SAndroid Build Coastguard Worker }
696*8975f5c5SAndroid Build Coastguard Worker 
detectConflictsBetweenEntries()697*8975f5c5SAndroid Build Coastguard Worker bool GPUTestExpectationsParser::detectConflictsBetweenEntries()
698*8975f5c5SAndroid Build Coastguard Worker {
699*8975f5c5SAndroid Build Coastguard Worker     bool rt = false;
700*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < mEntries.size(); ++i)
701*8975f5c5SAndroid Build Coastguard Worker     {
702*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = i + 1; j < mEntries.size(); ++j)
703*8975f5c5SAndroid Build Coastguard Worker         {
704*8975f5c5SAndroid Build Coastguard Worker             const GPUTestExpectationEntry &entryI = mEntries[i];
705*8975f5c5SAndroid Build Coastguard Worker             const GPUTestExpectationEntry &entryJ = mEntries[j];
706*8975f5c5SAndroid Build Coastguard Worker             if (entryI.testName == entryJ.testName &&
707*8975f5c5SAndroid Build Coastguard Worker                 ConditionsOverlap(entryI.conditions, entryJ.conditions))
708*8975f5c5SAndroid Build Coastguard Worker             {
709*8975f5c5SAndroid Build Coastguard Worker                 pushErrorMessage(kErrorMessage[kErrorEntriesOverlap], entryI.lineNumber,
710*8975f5c5SAndroid Build Coastguard Worker                                  entryJ.lineNumber);
711*8975f5c5SAndroid Build Coastguard Worker                 rt = true;
712*8975f5c5SAndroid Build Coastguard Worker             }
713*8975f5c5SAndroid Build Coastguard Worker         }
714*8975f5c5SAndroid Build Coastguard Worker     }
715*8975f5c5SAndroid Build Coastguard Worker     return rt;
716*8975f5c5SAndroid Build Coastguard Worker }
717*8975f5c5SAndroid Build Coastguard Worker 
718*8975f5c5SAndroid Build Coastguard Worker std::vector<GPUTestExpectationsParser::GPUTestExpectationEntry>
getUnusedExpectations() const719*8975f5c5SAndroid Build Coastguard Worker GPUTestExpectationsParser::getUnusedExpectations() const
720*8975f5c5SAndroid Build Coastguard Worker {
721*8975f5c5SAndroid Build Coastguard Worker     std::vector<GPUTestExpectationsParser::GPUTestExpectationEntry> unusedExpectations;
722*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < mEntries.size(); ++i)
723*8975f5c5SAndroid Build Coastguard Worker     {
724*8975f5c5SAndroid Build Coastguard Worker         if (!mEntries[i].used)
725*8975f5c5SAndroid Build Coastguard Worker         {
726*8975f5c5SAndroid Build Coastguard Worker             unusedExpectations.push_back(mEntries[i]);
727*8975f5c5SAndroid Build Coastguard Worker         }
728*8975f5c5SAndroid Build Coastguard Worker     }
729*8975f5c5SAndroid Build Coastguard Worker     return unusedExpectations;
730*8975f5c5SAndroid Build Coastguard Worker }
731*8975f5c5SAndroid Build Coastguard Worker 
pushErrorMessage(const std::string & message,size_t lineNumber)732*8975f5c5SAndroid Build Coastguard Worker void GPUTestExpectationsParser::pushErrorMessage(const std::string &message, size_t lineNumber)
733*8975f5c5SAndroid Build Coastguard Worker {
734*8975f5c5SAndroid Build Coastguard Worker     mErrorMessages.push_back("Line " + ToString(lineNumber) + " : " + message.c_str());
735*8975f5c5SAndroid Build Coastguard Worker }
736*8975f5c5SAndroid Build Coastguard Worker 
pushErrorMessage(const std::string & message,size_t entry1LineNumber,size_t entry2LineNumber)737*8975f5c5SAndroid Build Coastguard Worker void GPUTestExpectationsParser::pushErrorMessage(const std::string &message,
738*8975f5c5SAndroid Build Coastguard Worker                                                  size_t entry1LineNumber,
739*8975f5c5SAndroid Build Coastguard Worker                                                  size_t entry2LineNumber)
740*8975f5c5SAndroid Build Coastguard Worker {
741*8975f5c5SAndroid Build Coastguard Worker     mErrorMessages.push_back("Line " + ToString(entry1LineNumber) + " and " +
742*8975f5c5SAndroid Build Coastguard Worker                              ToString(entry2LineNumber) + " : " + message.c_str());
743*8975f5c5SAndroid Build Coastguard Worker }
744*8975f5c5SAndroid Build Coastguard Worker 
GPUTestExpectationEntry()745*8975f5c5SAndroid Build Coastguard Worker GPUTestExpectationsParser::GPUTestExpectationEntry::GPUTestExpectationEntry()
746*8975f5c5SAndroid Build Coastguard Worker     : testExpectation(0), lineNumber(0)
747*8975f5c5SAndroid Build Coastguard Worker {}
748*8975f5c5SAndroid Build Coastguard Worker 
749*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
750