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