Merge "Do not normalize binary path in xs::PosixTestProcess"
[platform/upstream/VK-GL-CTS.git] / modules / internal / ditFrameworkTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Internal Test Module
3  * ---------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Miscellaneous framework tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "ditFrameworkTests.hpp"
25 #include "ditTextureFormatTests.hpp"
26 #include "ditVulkanTests.hpp"
27
28 #include "tcuFloatFormat.hpp"
29 #include "tcuEither.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuCommandLine.hpp"
32
33 #include "rrRenderer.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "tcuVectorUtil.hpp"
36 #include "tcuFloat.hpp"
37
38 #include "deRandom.hpp"
39 #include "deArrayUtil.hpp"
40
41 namespace dit
42 {
43
44 namespace
45 {
46
47 using std::string;
48 using std::vector;
49 using tcu::TestLog;
50
51 struct MatchCase
52 {
53         enum Expected { NO_MATCH, MATCH_GROUP, MATCH_CASE, EXPECTED_LAST };
54
55         const char*     path;
56         Expected        expected;
57 };
58
59 const char* getMatchCaseExpectedDesc (MatchCase::Expected expected)
60 {
61         static const char* descs[] =
62         {
63                 "no match",
64                 "group to match",
65                 "case to match"
66         };
67         return de::getSizedArrayElement<MatchCase::EXPECTED_LAST>(descs, expected);
68 }
69
70 class CaseListParserCase : public tcu::TestCase
71 {
72 public:
73         CaseListParserCase (tcu::TestContext& testCtx, const char* name, const char* caseList, const MatchCase* subCases, int numSubCases)
74                 : tcu::TestCase (testCtx, name, "")
75                 , m_caseList    (caseList)
76                 , m_subCases    (subCases)
77                 , m_numSubCases (numSubCases)
78         {
79         }
80
81         IterateResult iterate (void)
82         {
83                 TestLog&                        log             = m_testCtx.getLog();
84                 tcu::CommandLine        cmdLine;
85                 int                                     numPass = 0;
86
87                 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
88
89                 {
90                         const char* argv[] =
91                         {
92                                 "deqp",
93                                 "--deqp-caselist",
94                                 m_caseList
95                         };
96
97                         if (!cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
98                                 TCU_FAIL("Failed to parse case list");
99                 }
100
101                 for (int subCaseNdx = 0; subCaseNdx < m_numSubCases; subCaseNdx++)
102                 {
103                         const MatchCase&        curCase         = m_subCases[subCaseNdx];
104                         bool                            matchGroup;
105                         bool                            matchCase;
106
107                         log << TestLog::Message << "Checking \"" << curCase.path << "\""
108                                                                         << ", expecting " << getMatchCaseExpectedDesc(curCase.expected)
109                                 << TestLog::EndMessage;
110
111                         matchGroup      = cmdLine.checkTestGroupName(curCase.path);
112                         matchCase       = cmdLine.checkTestCaseName(curCase.path);
113
114                         if ((matchGroup == (curCase.expected == MatchCase::MATCH_GROUP)) &&
115                                 (matchCase      == (curCase.expected == MatchCase::MATCH_CASE)))
116                         {
117                                 log << TestLog::Message << "   pass" << TestLog::EndMessage;
118                                 numPass += 1;
119                         }
120                         else
121                                 log << TestLog::Message << "   FAIL!" << TestLog::EndMessage;
122                 }
123
124                 m_testCtx.setTestResult((numPass == m_numSubCases) ? QP_TEST_RESULT_PASS        : QP_TEST_RESULT_FAIL,
125                                                                 (numPass == m_numSubCases) ? "All passed"                       : "Unexpected match result");
126
127                 return STOP;
128         }
129
130 private:
131         const char* const                       m_caseList;
132         const MatchCase* const          m_subCases;
133         const int                                       m_numSubCases;
134 };
135
136 class NegativeCaseListCase : public tcu::TestCase
137 {
138 public:
139         NegativeCaseListCase (tcu::TestContext& testCtx, const char* name, const char* caseList)
140                 : tcu::TestCase (testCtx, name, "")
141                 , m_caseList    (caseList)
142         {
143         }
144
145         IterateResult iterate (void)
146         {
147                 TestLog&                        log             = m_testCtx.getLog();
148                 tcu::CommandLine        cmdLine;
149
150                 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
151
152                 {
153                         const char* argv[] =
154                         {
155                                 "deqp",
156                                 "--deqp-caselist",
157                                 m_caseList
158                         };
159
160                         if (cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
161                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Parsing passed, should have failed");
162                         else
163                                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Parsing failed as expected");
164                 }
165
166                 return STOP;
167         }
168
169 private:
170         const char* const       m_caseList;
171 };
172
173 class TrieParserTests : public tcu::TestCaseGroup
174 {
175 public:
176         TrieParserTests (tcu::TestContext& testCtx)
177                 : tcu::TestCaseGroup(testCtx, "trie", "Test case trie parser tests")
178         {
179         }
180
181         void init (void)
182         {
183                 {
184                         static const char* const        caseList        = "{test}";
185                         static const MatchCase          subCases[]      =
186                         {
187                                 { "test",               MatchCase::MATCH_CASE   },
188                                 { "test.cd",    MatchCase::NO_MATCH             },
189                         };
190                         addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
191                 }
192                 {
193                         static const char* const        caseList        = "{a{b}}";
194                         static const MatchCase          subCases[]      =
195                         {
196                                 { "a",          MatchCase::MATCH_GROUP  },
197                                 { "b",          MatchCase::NO_MATCH             },
198                                 { "a.b",        MatchCase::MATCH_CASE   },
199                                 { "a.a",        MatchCase::NO_MATCH             },
200                         };
201                         addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
202                 }
203                 {
204                         static const char* const        caseList        = "{a{b,c}}";
205                         static const MatchCase          subCases[]      =
206                         {
207                                 { "a",          MatchCase::MATCH_GROUP  },
208                                 { "b",          MatchCase::NO_MATCH             },
209                                 { "a.b",        MatchCase::MATCH_CASE   },
210                                 { "a.a",        MatchCase::NO_MATCH             },
211                                 { "a.c",        MatchCase::MATCH_CASE   },
212                         };
213                         addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
214                 }
215                 {
216                         static const char* const        caseList        = "{a{b},c{d,e}}";
217                         static const MatchCase          subCases[]      =
218                         {
219                                 { "a",          MatchCase::MATCH_GROUP  },
220                                 { "b",          MatchCase::NO_MATCH             },
221                                 { "a.b",        MatchCase::MATCH_CASE   },
222                                 { "a.c",        MatchCase::NO_MATCH             },
223                                 { "a.d",        MatchCase::NO_MATCH             },
224                                 { "a.e",        MatchCase::NO_MATCH             },
225                                 { "c",          MatchCase::MATCH_GROUP  },
226                                 { "c.b",        MatchCase::NO_MATCH             },
227                                 { "c.d",        MatchCase::MATCH_CASE   },
228                                 { "c.e",        MatchCase::MATCH_CASE   },
229                         };
230                         addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
231                 }
232                 {
233                         static const char* const        caseList        = "{a,c{d,e}}";
234                         static const MatchCase          subCases[]      =
235                         {
236                                 { "a",          MatchCase::MATCH_CASE   },
237                                 { "b",          MatchCase::NO_MATCH             },
238                                 { "a.b",        MatchCase::NO_MATCH             },
239                                 { "a.c",        MatchCase::NO_MATCH             },
240                                 { "a.d",        MatchCase::NO_MATCH             },
241                                 { "a.e",        MatchCase::NO_MATCH             },
242                                 { "c",          MatchCase::MATCH_GROUP  },
243                                 { "c.b",        MatchCase::NO_MATCH             },
244                                 { "c.d",        MatchCase::MATCH_CASE   },
245                                 { "c.e",        MatchCase::MATCH_CASE   },
246                         };
247                         addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
248                 }
249                 {
250                         static const char* const        caseList        = "{c{d,e},a}";
251                         static const MatchCase          subCases[]      =
252                         {
253                                 { "a",          MatchCase::MATCH_CASE   },
254                                 { "b",          MatchCase::NO_MATCH             },
255                                 { "a.b",        MatchCase::NO_MATCH             },
256                                 { "a.c",        MatchCase::NO_MATCH             },
257                                 { "a.d",        MatchCase::NO_MATCH             },
258                                 { "a.e",        MatchCase::NO_MATCH             },
259                                 { "c",          MatchCase::MATCH_GROUP  },
260                                 { "c.b",        MatchCase::NO_MATCH             },
261                                 { "c.d",        MatchCase::MATCH_CASE   },
262                                 { "c.e",        MatchCase::MATCH_CASE   },
263                         };
264                         addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
265                 }
266                 {
267                         static const char* const        caseList        = "{test}\r";
268                         static const MatchCase          subCases[]      =
269                         {
270                                 { "test",               MatchCase::MATCH_CASE   },
271                                 { "test.cd",    MatchCase::NO_MATCH             },
272                         };
273                         addChild(new CaseListParserCase(m_testCtx, "trailing_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
274                 }
275                 {
276                         static const char* const        caseList        = "{test}\n";
277                         static const MatchCase          subCases[]      =
278                         {
279                                 { "test",               MatchCase::MATCH_CASE   },
280                                 { "test.cd",    MatchCase::NO_MATCH             },
281                         };
282                         addChild(new CaseListParserCase(m_testCtx, "trailing_lf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
283                 }
284                 {
285                         static const char* const        caseList        = "{test}\r\n";
286                         static const MatchCase          subCases[]      =
287                         {
288                                 { "test",               MatchCase::MATCH_CASE   },
289                                 { "test.cd",    MatchCase::NO_MATCH             },
290                         };
291                         addChild(new CaseListParserCase(m_testCtx, "trailing_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
292                 }
293
294                 // Negative tests
295                 addChild(new NegativeCaseListCase(m_testCtx, "empty_string",                    ""));
296                 addChild(new NegativeCaseListCase(m_testCtx, "empty_line",                              "\n"));
297                 addChild(new NegativeCaseListCase(m_testCtx, "empty_root",                              "{}"));
298                 addChild(new NegativeCaseListCase(m_testCtx, "empty_group",                             "{test{}}"));
299                 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_1",              "{{}}"));
300                 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_2",              "{{test}}"));
301                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_1",             "{"));
302                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_2",             "{test"));
303                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_3",             "{test,"));
304                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_4",             "{test{a}"));
305                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_5",             "{a,b"));
306                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_1",    "{test{"));
307                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_2",    "{test{a"));
308                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_3",    "{test{a,"));
309                 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_4",    "{test{a,b"));
310                 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_1",               "{a,,b}"));
311                 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_2",               "{,b}"));
312                 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_3",               "{a,}"));
313                 addChild(new NegativeCaseListCase(m_testCtx, "no_separator",                    "{a{b}c}"));
314                 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_1",                  "{a.b}"));
315                 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_2",                  "{a[]}"));
316                 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_1",                 "{a}}"));
317                 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_2",                 "{a}x"));
318                 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_1",              "{\na}"));
319                 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_2",              "{a\n,b}"));
320                 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_3",              "{a,\nb}"));
321                 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_4",              "{a{b\n}}"));
322                 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_5",              "{a{b}\n}"));
323         }
324 };
325
326 class ListParserTests : public tcu::TestCaseGroup
327 {
328 public:
329         ListParserTests (tcu::TestContext& testCtx)
330                 : tcu::TestCaseGroup(testCtx, "list", "Test case list parser tests")
331         {
332         }
333
334         void init (void)
335         {
336                 {
337                         static const char* const        caseList        = "test";
338                         static const MatchCase          subCases[]      =
339                         {
340                                 { "test",               MatchCase::MATCH_CASE   },
341                                 { "test.cd",    MatchCase::NO_MATCH             },
342                         };
343                         addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
344                 }
345                 {
346                         static const char* const        caseList        = "a.b";
347                         static const MatchCase          subCases[]      =
348                         {
349                                 { "a",          MatchCase::MATCH_GROUP  },
350                                 { "b",          MatchCase::NO_MATCH             },
351                                 { "a.b",        MatchCase::MATCH_CASE   },
352                                 { "a.a",        MatchCase::NO_MATCH             },
353                         };
354                         addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
355                 }
356                 {
357                         static const char* const        caseList        = "a.b\na.c";
358                         static const MatchCase          subCases[]      =
359                         {
360                                 { "a",          MatchCase::MATCH_GROUP  },
361                                 { "b",          MatchCase::NO_MATCH             },
362                                 { "a.b",        MatchCase::MATCH_CASE   },
363                                 { "a.a",        MatchCase::NO_MATCH             },
364                                 { "a.c",        MatchCase::MATCH_CASE   },
365                         };
366                         addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
367                 }
368                 {
369                         static const char* const        caseList        = "a.b\na.c";
370                         static const MatchCase          subCases[]      =
371                         {
372                                 { "a",          MatchCase::MATCH_GROUP  },
373                                 { "b",          MatchCase::NO_MATCH             },
374                                 { "a.b",        MatchCase::MATCH_CASE   },
375                                 { "a.a",        MatchCase::NO_MATCH             },
376                                 { "a.c",        MatchCase::MATCH_CASE   },
377                         };
378                         addChild(new CaseListParserCase(m_testCtx, "separator_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
379                 }
380                 {
381                         static const char* const        caseList        = "a.b\ra.c";
382                         static const MatchCase          subCases[]      =
383                         {
384                                 { "a",          MatchCase::MATCH_GROUP  },
385                                 { "b",          MatchCase::NO_MATCH             },
386                                 { "a.b",        MatchCase::MATCH_CASE   },
387                                 { "a.a",        MatchCase::NO_MATCH             },
388                                 { "a.c",        MatchCase::MATCH_CASE   },
389                         };
390                         addChild(new CaseListParserCase(m_testCtx, "separator_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
391                 }
392                 {
393                         static const char* const        caseList        = "a.b\r\na.c";
394                         static const MatchCase          subCases[]      =
395                         {
396                                 { "a",          MatchCase::MATCH_GROUP  },
397                                 { "b",          MatchCase::NO_MATCH             },
398                                 { "a.b",        MatchCase::MATCH_CASE   },
399                                 { "a.a",        MatchCase::NO_MATCH             },
400                                 { "a.c",        MatchCase::MATCH_CASE   },
401                         };
402                         addChild(new CaseListParserCase(m_testCtx, "separator_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
403                 }
404                 {
405                         static const char* const        caseList        = "a.b\na.c\n";
406                         static const MatchCase          subCases[]      =
407                         {
408                                 { "a",          MatchCase::MATCH_GROUP  },
409                                 { "b",          MatchCase::NO_MATCH             },
410                                 { "a.b",        MatchCase::MATCH_CASE   },
411                                 { "a.a",        MatchCase::NO_MATCH             },
412                                 { "a.c",        MatchCase::MATCH_CASE   },
413                         };
414                         addChild(new CaseListParserCase(m_testCtx, "end_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
415                 }
416                 {
417                         static const char* const        caseList        = "a.b\na.c\r";
418                         static const MatchCase          subCases[]      =
419                         {
420                                 { "a",          MatchCase::MATCH_GROUP  },
421                                 { "b",          MatchCase::NO_MATCH             },
422                                 { "a.b",        MatchCase::MATCH_CASE   },
423                                 { "a.a",        MatchCase::NO_MATCH             },
424                                 { "a.c",        MatchCase::MATCH_CASE   },
425                         };
426                         addChild(new CaseListParserCase(m_testCtx, "end_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
427                 }
428                 {
429                         static const char* const        caseList        = "a.b\na.c\r\n";
430                         static const MatchCase          subCases[]      =
431                         {
432                                 { "a",          MatchCase::MATCH_GROUP  },
433                                 { "b",          MatchCase::NO_MATCH             },
434                                 { "a.b",        MatchCase::MATCH_CASE   },
435                                 { "a.a",        MatchCase::NO_MATCH             },
436                                 { "a.c",        MatchCase::MATCH_CASE   },
437                         };
438                         addChild(new CaseListParserCase(m_testCtx, "end_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
439                 }
440                 {
441                         static const char* const        caseList        = "a.b\nc.d\nc.e";
442                         static const MatchCase          subCases[]      =
443                         {
444                                 { "a",          MatchCase::MATCH_GROUP  },
445                                 { "b",          MatchCase::NO_MATCH             },
446                                 { "a.b",        MatchCase::MATCH_CASE   },
447                                 { "a.c",        MatchCase::NO_MATCH             },
448                                 { "a.d",        MatchCase::NO_MATCH             },
449                                 { "a.e",        MatchCase::NO_MATCH             },
450                                 { "c",          MatchCase::MATCH_GROUP  },
451                                 { "c.b",        MatchCase::NO_MATCH             },
452                                 { "c.d",        MatchCase::MATCH_CASE   },
453                                 { "c.e",        MatchCase::MATCH_CASE   },
454                         };
455                         addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
456                 }
457                 {
458                         static const char* const        caseList        = "a\nc.d\nc.e";
459                         static const MatchCase          subCases[]      =
460                         {
461                                 { "a",          MatchCase::MATCH_CASE   },
462                                 { "b",          MatchCase::NO_MATCH             },
463                                 { "a.b",        MatchCase::NO_MATCH             },
464                                 { "a.c",        MatchCase::NO_MATCH             },
465                                 { "a.d",        MatchCase::NO_MATCH             },
466                                 { "a.e",        MatchCase::NO_MATCH             },
467                                 { "c",          MatchCase::MATCH_GROUP  },
468                                 { "c.b",        MatchCase::NO_MATCH             },
469                                 { "c.d",        MatchCase::MATCH_CASE   },
470                                 { "c.e",        MatchCase::MATCH_CASE   },
471                         };
472                         addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
473                 }
474                 {
475                         static const char* const        caseList        = "c.d\nc.e\na";
476                         static const MatchCase          subCases[]      =
477                         {
478                                 { "a",          MatchCase::MATCH_CASE   },
479                                 { "b",          MatchCase::NO_MATCH             },
480                                 { "a.b",        MatchCase::NO_MATCH             },
481                                 { "a.c",        MatchCase::NO_MATCH             },
482                                 { "a.d",        MatchCase::NO_MATCH             },
483                                 { "a.e",        MatchCase::NO_MATCH             },
484                                 { "c",          MatchCase::MATCH_GROUP  },
485                                 { "c.b",        MatchCase::NO_MATCH             },
486                                 { "c.d",        MatchCase::MATCH_CASE   },
487                                 { "c.e",        MatchCase::MATCH_CASE   },
488                         };
489                         addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
490                 }
491                 {
492                         static const char* const        caseList        = "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.x";
493                         static const MatchCase          subCases[]      =
494                         {
495                                 { "a",                                                                                          MatchCase::MATCH_GROUP  },
496                                 { "b",                                                                                          MatchCase::NO_MATCH             },
497                                 { "a.b",                                                                                        MatchCase::MATCH_GROUP  },
498                                 { "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.x",      MatchCase::MATCH_CASE   },
499                         };
500                         addChild(new CaseListParserCase(m_testCtx, "long_name", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
501                 }
502                 {
503                         static const char* const        caseList        =
504                                 "a.b.c.d.e\n"
505                                 "a.b.c.f\n"
506                                 "x.y.z\n"
507                                 "a.b.c.d.g\n"
508                                 "a.b.c.x\n";
509                         static const MatchCase          subCases[]      =
510                         {
511                                 { "a",                          MatchCase::MATCH_GROUP  },
512                                 { "a.b",                        MatchCase::MATCH_GROUP  },
513                                 { "a.b.c.d.e",          MatchCase::MATCH_CASE   },
514                                 { "a.b.c.d.g",          MatchCase::MATCH_CASE   },
515                                 { "x.y",                        MatchCase::MATCH_GROUP  },
516                                 { "x.y.z",                      MatchCase::MATCH_CASE   },
517                                 { "a.b.c.f",            MatchCase::MATCH_CASE   },
518                                 { "a.b.c.x",            MatchCase::MATCH_CASE   },
519                         };
520                         addChild(new CaseListParserCase(m_testCtx, "partial_prefix", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
521                 }
522                 {
523                         static const char* const        caseList        =
524                                 "a.a.c.d\n"
525                                 "a.b.c.d\n";
526                         static const MatchCase          subCases[]      =
527                         {
528                                 { "a",                          MatchCase::MATCH_GROUP  },
529                                 { "a.a",                        MatchCase::MATCH_GROUP  },
530                                 { "a.b.c.d",            MatchCase::MATCH_CASE   },
531                                 { "a.b.c.d",            MatchCase::MATCH_CASE   },
532                         };
533                         addChild(new CaseListParserCase(m_testCtx, "reparenting", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
534                 }
535
536                 // Negative tests
537                 addChild(new NegativeCaseListCase(m_testCtx, "empty_string",                    ""));
538                 addChild(new NegativeCaseListCase(m_testCtx, "empty_line",                              "\n"));
539                 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name",                ".test"));
540                 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name",                 "test."));
541         }
542 };
543
544 class CaseListParserTests : public tcu::TestCaseGroup
545 {
546 public:
547         CaseListParserTests (tcu::TestContext& testCtx)
548                 : tcu::TestCaseGroup(testCtx, "case_list_parser", "Test case list parser tests")
549         {
550         }
551
552         void init (void)
553         {
554                 addChild(new TrieParserTests(m_testCtx));
555                 addChild(new ListParserTests(m_testCtx));
556         }
557 };
558
559 inline deUint32 ulpDiff (float a, float b)
560 {
561         const deUint32 ab = tcu::Float32(a).bits();
562         const deUint32 bb = tcu::Float32(b).bits();
563         return de::max(ab, bb) - de::min(ab, bb);
564 }
565
566 template<int Size>
567 inline tcu::Vector<deUint32, Size> ulpDiff (const tcu::Vector<float, Size>& a, const tcu::Vector<float,  Size>& b)
568 {
569         tcu::Vector<deUint32, Size> res;
570         for (int ndx = 0; ndx < Size; ndx++)
571                 res[ndx] = ulpDiff(a[ndx], b[ndx]);
572         return res;
573 }
574
575 class ConstantInterpolationTest : public tcu::TestCase
576 {
577 public:
578         ConstantInterpolationTest (tcu::TestContext& testCtx)
579                 : tcu::TestCase(testCtx, "const_interpolation", "Constant value interpolation")
580         {
581                 const int supportedMsaaLevels[] = {1, 2, 4, 8, 16};
582
583                 for (int msaaNdx = 0; msaaNdx < DE_LENGTH_OF_ARRAY(supportedMsaaLevels); msaaNdx++)
584                 {
585                         const int numSamples = supportedMsaaLevels[msaaNdx];
586                         {
587                                 SubCase c;
588                                 c.rtSize        = tcu::IVec3(128, 128, numSamples);
589                                 c.vtx[0]        = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
590                                 c.vtx[1]        = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
591                                 c.vtx[2]        = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
592                                 c.varying       = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
593                                 m_cases.push_back(c);
594                         }
595
596                         {
597                                 SubCase c;
598                                 c.rtSize        = tcu::IVec3(128, 128, numSamples);
599                                 c.vtx[0]        = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
600                                 c.vtx[1]        = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
601                                 c.vtx[2]        = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
602                                 c.varying       = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
603                                 m_cases.push_back(c);
604                         }
605                         {
606                                 SubCase c;
607                                 c.rtSize        = tcu::IVec3(129, 113, numSamples);
608                                 c.vtx[0]        = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
609                                 c.vtx[1]        = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
610                                 c.vtx[2]        = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
611                                 c.varying       = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
612                                 m_cases.push_back(c);
613                         }
614                         {
615                                 SubCase c;
616                                 c.rtSize        = tcu::IVec3(107, 131, numSamples);
617                                 c.vtx[0]        = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
618                                 c.vtx[1]        = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
619                                 c.vtx[2]        = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
620                                 c.varying       = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
621                                 m_cases.push_back(c);
622                         }
623                 }
624
625                 {
626                         de::Random rnd(0x89423f);
627                         for (int ndx = 0; ndx < 25; ndx++)
628                         {
629                                 const float     depth   = rnd.getFloat()*2.0f - 1.0f;
630                                 SubCase         c;
631
632                                 c.rtSize.x() = rnd.getInt(16, 256);
633                                 c.rtSize.y() = rnd.getInt(16, 256);
634                                 c.rtSize.z() = rnd.choose<int>(DE_ARRAY_BEGIN(supportedMsaaLevels), DE_ARRAY_END(supportedMsaaLevels));
635
636                                 for (int vtxNdx = 0; vtxNdx < DE_LENGTH_OF_ARRAY(c.vtx); vtxNdx++)
637                                 {
638                                         c.vtx[vtxNdx].x() = rnd.getFloat()*2.0f - 1.0f;
639                                         c.vtx[vtxNdx].y() = rnd.getFloat()*2.0f - 1.0f;
640                                         c.vtx[vtxNdx].z() = depth;
641                                         c.vtx[vtxNdx].w() = 1.0f;
642                                 }
643
644                                 for (int compNdx = 0; compNdx < 4; compNdx++)
645                                 {
646                                         float v;
647                                         do
648                                         {
649                                                 v = tcu::Float32(rnd.getUint32()).asFloat();
650                                         } while (deFloatIsInf(v) || deFloatIsNaN(v));
651                                         c.varying[compNdx] = v;
652                                 }
653                                 m_cases.push_back(c);
654                         }
655                 }
656         }
657
658         void init (void)
659         {
660                 m_caseIter = m_cases.begin();
661                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All iterations passed");
662         }
663
664         IterateResult iterate (void)
665         {
666                 {
667                         tcu::ScopedLogSection section(m_testCtx.getLog(), "SubCase", "");
668                         runCase(*m_caseIter);
669                 }
670                 return (++m_caseIter != m_cases.end()) ? CONTINUE : STOP;
671         }
672
673 protected:
674         struct SubCase
675         {
676                 tcu::IVec3      rtSize; // (width, height, samples)
677                 tcu::Vec4       vtx[3];
678                 tcu::Vec4       varying;
679         };
680
681         void runCase (const SubCase& subCase)
682         {
683                 using namespace tcu;
684
685                 const deUint32  maxColorUlpDiff = 2;
686                 const deUint32  maxDepthUlpDiff = 0;
687
688                 const int               width                   = subCase.rtSize.x();
689                 const int               height                  = subCase.rtSize.y();
690                 const int               numSamples              = subCase.rtSize.z();
691                 const float             zn                              = 0.0f;
692                 const float             zf                              = 1.0f;
693
694                 TextureLevel    interpolated    (TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), numSamples, width, height);
695                 TextureLevel    depthStencil    (TextureFormat(TextureFormat::DS, TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV), numSamples, width, height);
696
697                 m_testCtx.getLog() << TestLog::Message
698                                                    << "RT size (w, h, #samples) = " << subCase.rtSize << "\n"
699                                                    << "vtx[0] = " << subCase.vtx[0] << "\n"
700                                                    << "vtx[1] = " << subCase.vtx[1] << "\n"
701                                                    << "vtx[2] = " << subCase.vtx[2] << "\n"
702                                                    << "color = " << subCase.varying
703                                                    << TestLog::EndMessage;
704
705                 clear                   (interpolated.getAccess(), subCase.varying - Vec4(0.0f, 0.0f, 0.0f, 1.0f));
706                 clearDepth              (depthStencil.getAccess(), 0.0f);
707                 clearStencil    (depthStencil.getAccess(), 0);
708
709                 {
710                         class VtxShader : public rr::VertexShader
711                         {
712                         public:
713                                 VtxShader (void)
714                                         : rr::VertexShader(2, 1)
715                                 {
716                                         m_inputs[0].type        = rr::GENERICVECTYPE_FLOAT;
717                                         m_inputs[1].type        = rr::GENERICVECTYPE_FLOAT;
718                                         m_outputs[0].type       = rr::GENERICVECTYPE_FLOAT;
719                                 }
720
721                                 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
722                                 {
723                                         for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
724                                         {
725                                                 rr::readVertexAttrib(packets[packetNdx]->position, inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
726                                                 packets[packetNdx]->outputs[0] = rr::readVertexAttribFloat(inputs[1], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
727                                         }
728                                 }
729                         } vtxShader;
730
731                         class FragShader : public rr::FragmentShader
732                         {
733                         public:
734                                 FragShader (void)
735                                         : rr::FragmentShader(1, 1)
736                                 {
737                                         m_inputs[0].type        = rr::GENERICVECTYPE_FLOAT;
738                                         m_outputs[0].type       = rr::GENERICVECTYPE_FLOAT;
739                                 }
740
741                                 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
742                                 {
743                                         for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
744                                         {
745                                                 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
746                                                 {
747                                                         const tcu::Vec4 interp = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
748                                                         rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, interp);
749                                                 }
750                                         }
751                                 }
752                         } fragShader;
753
754                         const rr::Program                                               program                 (&vtxShader, &fragShader);
755
756                         const rr::MultisamplePixelBufferAccess  colorAccess             = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(interpolated.getAccess());
757                         const rr::MultisamplePixelBufferAccess  dsAccess                = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess());
758                         const rr::RenderTarget                                  renderTarget    (colorAccess, dsAccess, dsAccess);
759                         const rr::VertexAttrib                                  vertexAttribs[] =
760                         {
761                                 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, 0, 0, subCase.vtx),
762                                 rr::VertexAttrib(subCase.varying)
763                         };
764                         rr::ViewportState                                               viewport                (colorAccess);
765                         rr::RenderState                                                 state                   (viewport);
766                         const rr::DrawCommand                                   drawCmd                 (state, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), vertexAttribs, rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0));
767                         const rr::Renderer                                              renderer;
768
769                         viewport.zn     = zn;
770                         viewport.zf     = zf;
771
772                         state.fragOps.depthTestEnabled                                                  = true;
773                         state.fragOps.depthFunc                                                                 = rr::TESTFUNC_ALWAYS;
774                         state.fragOps.stencilTestEnabled                                                = true;
775                         state.fragOps.stencilStates[rr::FACETYPE_BACK].func             = rr::TESTFUNC_ALWAYS;
776                         state.fragOps.stencilStates[rr::FACETYPE_BACK].dpPass   = rr::STENCILOP_INCR;
777                         state.fragOps.stencilStates[rr::FACETYPE_FRONT]                 = state.fragOps.stencilStates[rr::FACETYPE_BACK];
778
779                         renderer.draw(drawCmd);
780                 }
781
782                 // Verify interpolated values
783                 {
784                         TextureLevel                                    resolvedColor                   (interpolated.getFormat(), width, height); // For debugging
785                         TextureLevel                                    resolvedDepthStencil    (depthStencil.getFormat(), width, height); // For debugging
786                         TextureLevel                                    errorMask                               (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height);
787                         const ConstPixelBufferAccess    interpAccess                    = interpolated.getAccess();
788                         const ConstPixelBufferAccess    dsAccess                                = depthStencil.getAccess();
789                         const PixelBufferAccess                 errorAccess                             = errorMask.getAccess();
790                         int                                                             numCoveredSamples               = 0;
791                         int                                                             numFailedColorSamples   = 0;
792                         int                                                             numFailedDepthSamples   = 0;
793                         const bool                                              verifyDepth                             = (subCase.vtx[0].z() == subCase.vtx[1].z()) &&
794                                                                                                                                           (subCase.vtx[1].z() == subCase.vtx[2].z());
795                         const float                                             refDepth                                = subCase.vtx[0].z()*(zf - zn)/2.0f + (zn + zf)/2.0f;
796
797                         rr::resolveMultisampleBuffer(resolvedColor.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(interpolated.getAccess()));
798                         rr::resolveMultisampleBuffer(resolvedDepthStencil.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess()));
799                         clear(errorAccess, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
800
801                         for (int y = 0; y < height; y++)
802                         {
803                                 for (int x = 0; x < width; x++)
804                                 {
805                                         for (int sampleNdx = 0; sampleNdx < numSamples; sampleNdx++)
806                                         {
807                                                 if (dsAccess.getPixStencil(sampleNdx, x, y) != 0)
808                                                 {
809                                                         const Vec4              color           = interpAccess.getPixel(sampleNdx, x, y);
810                                                         const UVec4             colorDiff       = ulpDiff(color, subCase.varying);
811                                                         const bool              colorOk         = boolAll(lessThanEqual(colorDiff, tcu::UVec4(maxColorUlpDiff)));
812
813                                                         const float             depth           = dsAccess.getPixDepth(sampleNdx, x, y);
814                                                         const deUint32  depthDiff       = ulpDiff(depth, refDepth);
815                                                         const bool              depthOk         = verifyDepth && (depthDiff <= maxDepthUlpDiff);
816
817                                                         const int               maxMsgs         = 10;
818
819                                                         numCoveredSamples += 1;
820
821                                                         if (!colorOk)
822                                                         {
823                                                                 numFailedColorSamples += 1;
824
825                                                                 if (numFailedColorSamples <= maxMsgs)
826                                                                         m_testCtx.getLog() << TestLog::Message
827                                                                                                            << "FAIL: " << tcu::IVec3(x, y, sampleNdx)
828                                                                                                            << " color ulp diff = " << colorDiff
829                                                                                                            << TestLog::EndMessage;
830                                                         }
831
832                                                         if (!depthOk)
833                                                                 numFailedDepthSamples += 1;
834
835                                                         if (!colorOk || !depthOk)
836                                                                 errorAccess.setPixel(errorAccess.getPixel(x, y) + Vec4(1.0f, -1.0f, 0.0f, 0.0f) / float(numSamples-1), x, y);
837                                                 }
838                                         }
839                                 }
840                         }
841
842                         m_testCtx.getLog() << TestLog::Image("ResolvedColor", "Resolved colorbuffer", resolvedColor)
843                                                            << TestLog::Image("ResolvedDepthStencil", "Resolved depth- & stencilbuffer", resolvedDepthStencil);
844
845                         if (numFailedColorSamples != 0 || numFailedDepthSamples != 0)
846                         {
847                                 m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
848
849                                 if (numFailedColorSamples != 0)
850                                         m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedColorSamples << " invalid color samples!" << TestLog::EndMessage;
851
852                                 if (numFailedDepthSamples != 0)
853                                         m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedDepthSamples << " invalid depth samples!" << TestLog::EndMessage;
854
855                                 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
856                                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid samples found");
857                         }
858
859                         m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedColorSamples) << " / " << numCoveredSamples << " color samples passed" << TestLog::EndMessage;
860                         m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedDepthSamples) << " / " << numCoveredSamples << " depth samples passed" << TestLog::EndMessage;
861                 }
862         }
863
864         vector<SubCase>                                 m_cases;
865         vector<SubCase>::const_iterator m_caseIter;
866 };
867
868 class CommonFrameworkTests : public tcu::TestCaseGroup
869 {
870 public:
871         CommonFrameworkTests (tcu::TestContext& testCtx)
872                 : tcu::TestCaseGroup(testCtx, "common", "Tests for the common utility framework")
873         {
874         }
875
876         void init (void)
877         {
878                 addChild(new SelfCheckCase(m_testCtx, "float_format","tcu::FloatFormat_selfTest()",
879                                                                    tcu::FloatFormat_selfTest));
880                 addChild(new SelfCheckCase(m_testCtx, "either","tcu::Either_selfTest()",
881                                                                    tcu::Either_selfTest));
882         }
883 };
884
885 class ReferenceRendererTests : public tcu::TestCaseGroup
886 {
887 public:
888         ReferenceRendererTests (tcu::TestContext& testCtx)
889                 : tcu::TestCaseGroup(testCtx, "reference_renderer", "Reference renderer tests")
890         {
891         }
892
893         void init (void)
894         {
895                 addChild(new ConstantInterpolationTest(m_testCtx));
896         }
897 };
898
899 } // anonymous
900
901 FrameworkTests::FrameworkTests (tcu::TestContext& testCtx)
902         : tcu::TestCaseGroup(testCtx, "framework", "Miscellaneous framework tests")
903 {
904 }
905
906 FrameworkTests::~FrameworkTests (void)
907 {
908 }
909
910 void FrameworkTests::init (void)
911 {
912         addChild(new CommonFrameworkTests       (m_testCtx));
913         addChild(new CaseListParserTests        (m_testCtx));
914         addChild(new ReferenceRendererTests     (m_testCtx));
915         addChild(createTextureFormatTests       (m_testCtx));
916         addChild(createVulkanTests                      (m_testCtx));
917 }
918
919 } // dit