1 /*-------------------------------------------------------------------------
2 * drawElements Internal Test Module
3 * ---------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Miscellaneous framework tests.
22 *//*--------------------------------------------------------------------*/
24 #include "ditFrameworkTests.hpp"
25 #include "tcuFloatFormat.hpp"
26 #include "tcuEither.hpp"
27 #include "tcuTestLog.hpp"
28 #include "tcuCommandLine.hpp"
30 #include "rrRenderer.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuVectorUtil.hpp"
33 #include "tcuFloat.hpp"
35 #include "deRandom.hpp"
36 #include "deArrayUtil.hpp"
50 enum Expected { NO_MATCH, MATCH_GROUP, MATCH_CASE, EXPECTED_LAST };
56 const char* getMatchCaseExpectedDesc (MatchCase::Expected expected)
58 static const char* descs[] =
64 return de::getSizedArrayElement<MatchCase::EXPECTED_LAST>(descs, expected);
67 class CaseListParserCase : public tcu::TestCase
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)
78 IterateResult iterate (void)
80 TestLog& log = m_testCtx.getLog();
81 tcu::CommandLine cmdLine;
84 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
94 if (!cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
95 TCU_FAIL("Failed to parse case list");
98 for (int subCaseNdx = 0; subCaseNdx < m_numSubCases; subCaseNdx++)
100 const MatchCase& curCase = m_subCases[subCaseNdx];
104 log << TestLog::Message << "Checking \"" << curCase.path << "\""
105 << ", expecting " << getMatchCaseExpectedDesc(curCase.expected)
106 << TestLog::EndMessage;
108 matchGroup = cmdLine.checkTestGroupName(curCase.path);
109 matchCase = cmdLine.checkTestCaseName(curCase.path);
111 if ((matchGroup == (curCase.expected == MatchCase::MATCH_GROUP)) &&
112 (matchCase == (curCase.expected == MatchCase::MATCH_CASE)))
114 log << TestLog::Message << " pass" << TestLog::EndMessage;
118 log << TestLog::Message << " FAIL!" << TestLog::EndMessage;
121 m_testCtx.setTestResult((numPass == m_numSubCases) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
122 (numPass == m_numSubCases) ? "All passed" : "Unexpected match result");
128 const char* const m_caseList;
129 const MatchCase* const m_subCases;
130 const int m_numSubCases;
133 class NegativeCaseListCase : public tcu::TestCase
136 NegativeCaseListCase (tcu::TestContext& testCtx, const char* name, const char* caseList)
137 : tcu::TestCase (testCtx, name, "")
138 , m_caseList (caseList)
142 IterateResult iterate (void)
144 TestLog& log = m_testCtx.getLog();
145 tcu::CommandLine cmdLine;
147 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
157 if (cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
158 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Parsing passed, should have failed");
160 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Parsing failed as expected");
167 const char* const m_caseList;
170 class TrieParserTests : public tcu::TestCaseGroup
173 TrieParserTests (tcu::TestContext& testCtx)
174 : tcu::TestCaseGroup(testCtx, "trie", "Test case trie parser tests")
181 static const char* const caseList = "{test}";
182 static const MatchCase subCases[] =
184 { "test", MatchCase::MATCH_CASE },
185 { "test.cd", MatchCase::NO_MATCH },
187 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
190 static const char* const caseList = "{a{b}}";
191 static const MatchCase subCases[] =
193 { "a", MatchCase::MATCH_GROUP },
194 { "b", MatchCase::NO_MATCH },
195 { "a.b", MatchCase::MATCH_CASE },
196 { "a.a", MatchCase::NO_MATCH },
198 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
201 static const char* const caseList = "{a{b,c}}";
202 static const MatchCase subCases[] =
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 },
210 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
213 static const char* const caseList = "{a{b},c{d,e}}";
214 static const MatchCase subCases[] =
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 },
227 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
230 static const char* const caseList = "{a,c{d,e}}";
231 static const MatchCase subCases[] =
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 },
244 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
247 static const char* const caseList = "{c{d,e},a}";
248 static const MatchCase subCases[] =
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 },
261 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
264 static const char* const caseList = "{test}\r";
265 static const MatchCase subCases[] =
267 { "test", MatchCase::MATCH_CASE },
268 { "test.cd", MatchCase::NO_MATCH },
270 addChild(new CaseListParserCase(m_testCtx, "trailing_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
273 static const char* const caseList = "{test}\n";
274 static const MatchCase subCases[] =
276 { "test", MatchCase::MATCH_CASE },
277 { "test.cd", MatchCase::NO_MATCH },
279 addChild(new CaseListParserCase(m_testCtx, "trailing_lf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
282 static const char* const caseList = "{test}\r\n";
283 static const MatchCase subCases[] =
285 { "test", MatchCase::MATCH_CASE },
286 { "test.cd", MatchCase::NO_MATCH },
288 addChild(new CaseListParserCase(m_testCtx, "trailing_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
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}"));
323 class ListParserTests : public tcu::TestCaseGroup
326 ListParserTests (tcu::TestContext& testCtx)
327 : tcu::TestCaseGroup(testCtx, "list", "Test case list parser tests")
334 static const char* const caseList = "test";
335 static const MatchCase subCases[] =
337 { "test", MatchCase::MATCH_CASE },
338 { "test.cd", MatchCase::NO_MATCH },
340 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
343 static const char* const caseList = "a.b";
344 static const MatchCase subCases[] =
346 { "a", MatchCase::MATCH_GROUP },
347 { "b", MatchCase::NO_MATCH },
348 { "a.b", MatchCase::MATCH_CASE },
349 { "a.a", MatchCase::NO_MATCH },
351 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
354 static const char* const caseList = "a.b\na.c";
355 static const MatchCase subCases[] =
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 },
363 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
366 static const char* const caseList = "a.b\na.c";
367 static const MatchCase subCases[] =
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 },
375 addChild(new CaseListParserCase(m_testCtx, "separator_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
378 static const char* const caseList = "a.b\ra.c";
379 static const MatchCase subCases[] =
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 },
387 addChild(new CaseListParserCase(m_testCtx, "separator_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
390 static const char* const caseList = "a.b\r\na.c";
391 static const MatchCase subCases[] =
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 },
399 addChild(new CaseListParserCase(m_testCtx, "separator_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
402 static const char* const caseList = "a.b\na.c\n";
403 static const MatchCase subCases[] =
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 },
411 addChild(new CaseListParserCase(m_testCtx, "end_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
414 static const char* const caseList = "a.b\na.c\r";
415 static const MatchCase subCases[] =
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 },
423 addChild(new CaseListParserCase(m_testCtx, "end_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
426 static const char* const caseList = "a.b\na.c\r\n";
427 static const MatchCase subCases[] =
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 },
435 addChild(new CaseListParserCase(m_testCtx, "end_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
438 static const char* const caseList = "a.b\nc.d\nc.e";
439 static const MatchCase subCases[] =
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 },
452 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
455 static const char* const caseList = "a\nc.d\nc.e";
456 static const MatchCase subCases[] =
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 },
469 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
472 static const char* const caseList = "c.d\nc.e\na";
473 static const MatchCase subCases[] =
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 },
486 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
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[] =
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 },
497 addChild(new CaseListParserCase(m_testCtx, "long_name", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
500 static const char* const caseList =
506 static const MatchCase subCases[] =
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 },
517 addChild(new CaseListParserCase(m_testCtx, "partial_prefix", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
520 static const char* const caseList =
523 static const MatchCase subCases[] =
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 },
530 addChild(new CaseListParserCase(m_testCtx, "reparenting", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
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."));
541 class CaseListParserTests : public tcu::TestCaseGroup
544 CaseListParserTests (tcu::TestContext& testCtx)
545 : tcu::TestCaseGroup(testCtx, "case_list_parser", "Test case list parser tests")
551 addChild(new TrieParserTests(m_testCtx));
552 addChild(new ListParserTests(m_testCtx));
556 inline deUint32 ulpDiff (float a, float b)
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);
564 inline tcu::Vector<deUint32, Size> ulpDiff (const tcu::Vector<float, Size>& a, const tcu::Vector<float, Size>& b)
566 tcu::Vector<deUint32, Size> res;
567 for (int ndx = 0; ndx < Size; ndx++)
568 res[ndx] = ulpDiff(a[ndx], b[ndx]);
572 class ConstantInterpolationTest : public tcu::TestCase
575 ConstantInterpolationTest (tcu::TestContext& testCtx)
576 : tcu::TestCase(testCtx, "const_interpolation", "Constant value interpolation")
578 const int supportedMsaaLevels[] = {1, 2, 4, 8, 16};
580 for (int msaaNdx = 0; msaaNdx < DE_LENGTH_OF_ARRAY(supportedMsaaLevels); msaaNdx++)
582 const int numSamples = supportedMsaaLevels[msaaNdx];
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);
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);
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);
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);
623 de::Random rnd(0x89423f);
624 for (int ndx = 0; ndx < 25; ndx++)
626 const float depth = rnd.getFloat()*2.0f - 1.0f;
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));
633 for (int vtxNdx = 0; vtxNdx < DE_LENGTH_OF_ARRAY(c.vtx); vtxNdx++)
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;
641 for (int compNdx = 0; compNdx < 4; compNdx++)
646 v = tcu::Float32(rnd.getUint32()).asFloat();
647 } while (deFloatIsInf(v) || deFloatIsNaN(v));
648 c.varying[compNdx] = v;
650 m_cases.push_back(c);
657 m_caseIter = m_cases.begin();
658 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All iterations passed");
661 IterateResult iterate (void)
664 tcu::ScopedLogSection section(m_testCtx.getLog(), "SubCase", "");
665 runCase(*m_caseIter);
667 return (++m_caseIter != m_cases.end()) ? CONTINUE : STOP;
673 tcu::IVec3 rtSize; // (width, height, samples)
678 void runCase (const SubCase& subCase)
682 const deUint32 maxColorUlpDiff = 2;
683 const deUint32 maxDepthUlpDiff = 0;
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;
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);
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;
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);
707 class VtxShader : public rr::VertexShader
711 : rr::VertexShader(2, 1)
713 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
714 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
715 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
718 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
720 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
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);
728 class FragShader : public rr::FragmentShader
732 : rr::FragmentShader(1, 1)
734 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
735 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
738 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
740 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
742 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
744 const tcu::Vec4 interp = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
745 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, interp);
751 const rr::Program program (&vtxShader, &fragShader);
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[] =
758 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, 0, 0, subCase.vtx),
759 rr::VertexAttrib(subCase.varying)
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;
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];
776 renderer.draw(drawCmd);
779 // Verify interpolated values
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;
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));
798 for (int y = 0; y < height; y++)
800 for (int x = 0; x < width; x++)
802 for (int sampleNdx = 0; sampleNdx < numSamples; sampleNdx++)
804 if (dsAccess.getPixStencil(sampleNdx, x, y) != 0)
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)));
810 const float depth = dsAccess.getPixDepth(sampleNdx, x, y);
811 const deUint32 depthDiff = ulpDiff(depth, refDepth);
812 const bool depthOk = verifyDepth && (depthDiff <= maxDepthUlpDiff);
814 const int maxMsgs = 10;
816 numCoveredSamples += 1;
820 numFailedColorSamples += 1;
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;
830 numFailedDepthSamples += 1;
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);
839 m_testCtx.getLog() << TestLog::Image("ResolvedColor", "Resolved colorbuffer", resolvedColor)
840 << TestLog::Image("ResolvedDepthStencil", "Resolved depth- & stencilbuffer", resolvedDepthStencil);
842 if (numFailedColorSamples != 0 || numFailedDepthSamples != 0)
844 m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
846 if (numFailedColorSamples != 0)
847 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedColorSamples << " invalid color samples!" << TestLog::EndMessage;
849 if (numFailedDepthSamples != 0)
850 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedDepthSamples << " invalid depth samples!" << TestLog::EndMessage;
852 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
853 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid samples found");
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;
861 vector<SubCase> m_cases;
862 vector<SubCase>::const_iterator m_caseIter;
865 class CommonFrameworkTests : public tcu::TestCaseGroup
868 CommonFrameworkTests (tcu::TestContext& testCtx)
869 : tcu::TestCaseGroup(testCtx, "common", "Tests for the common utility framework")
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));
882 class ReferenceRendererTests : public tcu::TestCaseGroup
885 ReferenceRendererTests (tcu::TestContext& testCtx)
886 : tcu::TestCaseGroup(testCtx, "reference_renderer", "Reference renderer tests")
892 addChild(new ConstantInterpolationTest(m_testCtx));
898 FrameworkTests::FrameworkTests (tcu::TestContext& testCtx)
899 : tcu::TestCaseGroup(testCtx, "framework", "Miscellaneous framework tests")
903 FrameworkTests::~FrameworkTests (void)
907 void FrameworkTests::init (void)
909 addChild(new CommonFrameworkTests (m_testCtx));
910 addChild(new CaseListParserTests (m_testCtx));
911 addChild(new ReferenceRendererTests (m_testCtx));