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 "deRandom.hpp"
34 #include "tcuFloat.hpp"
48 enum Expected { NO_MATCH, MATCH_GROUP, MATCH_CASE, EXPECTED_LAST };
54 const char* getMatchCaseExpectedDesc (MatchCase::Expected expected)
56 static const char* descs[] =
62 return de::getSizedArrayElement<MatchCase::EXPECTED_LAST>(descs, expected);
65 class CaseListParserCase : public tcu::TestCase
68 CaseListParserCase (tcu::TestContext& testCtx, const char* name, const char* caseList, const MatchCase* subCases, int numSubCases)
69 : tcu::TestCase (testCtx, name, "")
70 , m_caseList (caseList)
71 , m_subCases (subCases)
72 , m_numSubCases (numSubCases)
76 IterateResult iterate (void)
78 TestLog& log = m_testCtx.getLog();
79 tcu::CommandLine cmdLine;
82 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
92 if (!cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
93 TCU_FAIL("Failed to parse case list");
96 for (int subCaseNdx = 0; subCaseNdx < m_numSubCases; subCaseNdx++)
98 const MatchCase& curCase = m_subCases[subCaseNdx];
102 log << TestLog::Message << "Checking \"" << curCase.path << "\""
103 << ", expecting " << getMatchCaseExpectedDesc(curCase.expected)
104 << TestLog::EndMessage;
106 matchGroup = cmdLine.checkTestGroupName(curCase.path);
107 matchCase = cmdLine.checkTestCaseName(curCase.path);
109 if ((matchGroup == (curCase.expected == MatchCase::MATCH_GROUP)) &&
110 (matchCase == (curCase.expected == MatchCase::MATCH_CASE)))
112 log << TestLog::Message << " pass" << TestLog::EndMessage;
116 log << TestLog::Message << " FAIL!" << TestLog::EndMessage;
119 m_testCtx.setTestResult((numPass == m_numSubCases) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
120 (numPass == m_numSubCases) ? "All passed" : "Unexpected match result");
126 const char* const m_caseList;
127 const MatchCase* const m_subCases;
128 const int m_numSubCases;
131 class NegativeCaseListCase : public tcu::TestCase
134 NegativeCaseListCase (tcu::TestContext& testCtx, const char* name, const char* caseList)
135 : tcu::TestCase (testCtx, name, "")
136 , m_caseList (caseList)
140 IterateResult iterate (void)
142 TestLog& log = m_testCtx.getLog();
143 tcu::CommandLine cmdLine;
145 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
155 if (cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
156 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Parsing passed, should have failed");
158 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Parsing failed as expected");
165 const char* const m_caseList;
168 class TrieParserTests : public tcu::TestCaseGroup
171 TrieParserTests (tcu::TestContext& testCtx)
172 : tcu::TestCaseGroup(testCtx, "trie", "Test case trie parser tests")
179 static const char* const caseList = "{test}";
180 static const MatchCase subCases[] =
182 { "test", MatchCase::MATCH_CASE },
183 { "test.cd", MatchCase::NO_MATCH },
185 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
188 static const char* const caseList = "{a{b}}";
189 static const MatchCase subCases[] =
191 { "a", MatchCase::MATCH_GROUP },
192 { "b", MatchCase::NO_MATCH },
193 { "a.b", MatchCase::MATCH_CASE },
194 { "a.a", MatchCase::NO_MATCH },
196 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
199 static const char* const caseList = "{a{b,c}}";
200 static const MatchCase subCases[] =
202 { "a", MatchCase::MATCH_GROUP },
203 { "b", MatchCase::NO_MATCH },
204 { "a.b", MatchCase::MATCH_CASE },
205 { "a.a", MatchCase::NO_MATCH },
206 { "a.c", MatchCase::MATCH_CASE },
208 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
211 static const char* const caseList = "{a{b},c{d,e}}";
212 static const MatchCase subCases[] =
214 { "a", MatchCase::MATCH_GROUP },
215 { "b", MatchCase::NO_MATCH },
216 { "a.b", MatchCase::MATCH_CASE },
217 { "a.c", MatchCase::NO_MATCH },
218 { "a.d", MatchCase::NO_MATCH },
219 { "a.e", MatchCase::NO_MATCH },
220 { "c", MatchCase::MATCH_GROUP },
221 { "c.b", MatchCase::NO_MATCH },
222 { "c.d", MatchCase::MATCH_CASE },
223 { "c.e", MatchCase::MATCH_CASE },
225 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
228 static const char* const caseList = "{a,c{d,e}}";
229 static const MatchCase subCases[] =
231 { "a", MatchCase::MATCH_CASE },
232 { "b", MatchCase::NO_MATCH },
233 { "a.b", MatchCase::NO_MATCH },
234 { "a.c", MatchCase::NO_MATCH },
235 { "a.d", MatchCase::NO_MATCH },
236 { "a.e", MatchCase::NO_MATCH },
237 { "c", MatchCase::MATCH_GROUP },
238 { "c.b", MatchCase::NO_MATCH },
239 { "c.d", MatchCase::MATCH_CASE },
240 { "c.e", MatchCase::MATCH_CASE },
242 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
245 static const char* const caseList = "{c{d,e},a}";
246 static const MatchCase subCases[] =
248 { "a", MatchCase::MATCH_CASE },
249 { "b", MatchCase::NO_MATCH },
250 { "a.b", MatchCase::NO_MATCH },
251 { "a.c", MatchCase::NO_MATCH },
252 { "a.d", MatchCase::NO_MATCH },
253 { "a.e", MatchCase::NO_MATCH },
254 { "c", MatchCase::MATCH_GROUP },
255 { "c.b", MatchCase::NO_MATCH },
256 { "c.d", MatchCase::MATCH_CASE },
257 { "c.e", MatchCase::MATCH_CASE },
259 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
262 static const char* const caseList = "{test}\r";
263 static const MatchCase subCases[] =
265 { "test", MatchCase::MATCH_CASE },
266 { "test.cd", MatchCase::NO_MATCH },
268 addChild(new CaseListParserCase(m_testCtx, "trailing_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
271 static const char* const caseList = "{test}\n";
272 static const MatchCase subCases[] =
274 { "test", MatchCase::MATCH_CASE },
275 { "test.cd", MatchCase::NO_MATCH },
277 addChild(new CaseListParserCase(m_testCtx, "trailing_lf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
280 static const char* const caseList = "{test}\r\n";
281 static const MatchCase subCases[] =
283 { "test", MatchCase::MATCH_CASE },
284 { "test.cd", MatchCase::NO_MATCH },
286 addChild(new CaseListParserCase(m_testCtx, "trailing_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
290 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", ""));
291 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n"));
292 addChild(new NegativeCaseListCase(m_testCtx, "empty_root", "{}"));
293 addChild(new NegativeCaseListCase(m_testCtx, "empty_group", "{test{}}"));
294 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_1", "{{}}"));
295 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_2", "{{test}}"));
296 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_1", "{"));
297 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_2", "{test"));
298 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_3", "{test,"));
299 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_4", "{test{a}"));
300 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_5", "{a,b"));
301 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_1", "{test{"));
302 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_2", "{test{a"));
303 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_3", "{test{a,"));
304 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_4", "{test{a,b"));
305 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_1", "{a,,b}"));
306 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_2", "{,b}"));
307 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_3", "{a,}"));
308 addChild(new NegativeCaseListCase(m_testCtx, "no_separator", "{a{b}c}"));
309 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_1", "{a.b}"));
310 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_2", "{a[]}"));
311 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_1", "{a}}"));
312 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_2", "{a}x"));
313 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_1", "{\na}"));
314 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_2", "{a\n,b}"));
315 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_3", "{a,\nb}"));
316 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_4", "{a{b\n}}"));
317 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_5", "{a{b}\n}"));
321 class ListParserTests : public tcu::TestCaseGroup
324 ListParserTests (tcu::TestContext& testCtx)
325 : tcu::TestCaseGroup(testCtx, "list", "Test case list parser tests")
332 static const char* const caseList = "test";
333 static const MatchCase subCases[] =
335 { "test", MatchCase::MATCH_CASE },
336 { "test.cd", MatchCase::NO_MATCH },
338 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
341 static const char* const caseList = "a.b";
342 static const MatchCase subCases[] =
344 { "a", MatchCase::MATCH_GROUP },
345 { "b", MatchCase::NO_MATCH },
346 { "a.b", MatchCase::MATCH_CASE },
347 { "a.a", MatchCase::NO_MATCH },
349 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
352 static const char* const caseList = "a.b\na.c";
353 static const MatchCase subCases[] =
355 { "a", MatchCase::MATCH_GROUP },
356 { "b", MatchCase::NO_MATCH },
357 { "a.b", MatchCase::MATCH_CASE },
358 { "a.a", MatchCase::NO_MATCH },
359 { "a.c", MatchCase::MATCH_CASE },
361 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
364 static const char* const caseList = "a.b\na.c";
365 static const MatchCase subCases[] =
367 { "a", MatchCase::MATCH_GROUP },
368 { "b", MatchCase::NO_MATCH },
369 { "a.b", MatchCase::MATCH_CASE },
370 { "a.a", MatchCase::NO_MATCH },
371 { "a.c", MatchCase::MATCH_CASE },
373 addChild(new CaseListParserCase(m_testCtx, "separator_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
376 static const char* const caseList = "a.b\ra.c";
377 static const MatchCase subCases[] =
379 { "a", MatchCase::MATCH_GROUP },
380 { "b", MatchCase::NO_MATCH },
381 { "a.b", MatchCase::MATCH_CASE },
382 { "a.a", MatchCase::NO_MATCH },
383 { "a.c", MatchCase::MATCH_CASE },
385 addChild(new CaseListParserCase(m_testCtx, "separator_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
388 static const char* const caseList = "a.b\r\na.c";
389 static const MatchCase subCases[] =
391 { "a", MatchCase::MATCH_GROUP },
392 { "b", MatchCase::NO_MATCH },
393 { "a.b", MatchCase::MATCH_CASE },
394 { "a.a", MatchCase::NO_MATCH },
395 { "a.c", MatchCase::MATCH_CASE },
397 addChild(new CaseListParserCase(m_testCtx, "separator_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
400 static const char* const caseList = "a.b\na.c\n";
401 static const MatchCase subCases[] =
403 { "a", MatchCase::MATCH_GROUP },
404 { "b", MatchCase::NO_MATCH },
405 { "a.b", MatchCase::MATCH_CASE },
406 { "a.a", MatchCase::NO_MATCH },
407 { "a.c", MatchCase::MATCH_CASE },
409 addChild(new CaseListParserCase(m_testCtx, "end_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
412 static const char* const caseList = "a.b\na.c\r";
413 static const MatchCase subCases[] =
415 { "a", MatchCase::MATCH_GROUP },
416 { "b", MatchCase::NO_MATCH },
417 { "a.b", MatchCase::MATCH_CASE },
418 { "a.a", MatchCase::NO_MATCH },
419 { "a.c", MatchCase::MATCH_CASE },
421 addChild(new CaseListParserCase(m_testCtx, "end_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
424 static const char* const caseList = "a.b\na.c\r\n";
425 static const MatchCase subCases[] =
427 { "a", MatchCase::MATCH_GROUP },
428 { "b", MatchCase::NO_MATCH },
429 { "a.b", MatchCase::MATCH_CASE },
430 { "a.a", MatchCase::NO_MATCH },
431 { "a.c", MatchCase::MATCH_CASE },
433 addChild(new CaseListParserCase(m_testCtx, "end_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
436 static const char* const caseList = "a.b\nc.d\nc.e";
437 static const MatchCase subCases[] =
439 { "a", MatchCase::MATCH_GROUP },
440 { "b", MatchCase::NO_MATCH },
441 { "a.b", MatchCase::MATCH_CASE },
442 { "a.c", MatchCase::NO_MATCH },
443 { "a.d", MatchCase::NO_MATCH },
444 { "a.e", MatchCase::NO_MATCH },
445 { "c", MatchCase::MATCH_GROUP },
446 { "c.b", MatchCase::NO_MATCH },
447 { "c.d", MatchCase::MATCH_CASE },
448 { "c.e", MatchCase::MATCH_CASE },
450 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
453 static const char* const caseList = "a\nc.d\nc.e";
454 static const MatchCase subCases[] =
456 { "a", MatchCase::MATCH_CASE },
457 { "b", MatchCase::NO_MATCH },
458 { "a.b", MatchCase::NO_MATCH },
459 { "a.c", MatchCase::NO_MATCH },
460 { "a.d", MatchCase::NO_MATCH },
461 { "a.e", MatchCase::NO_MATCH },
462 { "c", MatchCase::MATCH_GROUP },
463 { "c.b", MatchCase::NO_MATCH },
464 { "c.d", MatchCase::MATCH_CASE },
465 { "c.e", MatchCase::MATCH_CASE },
467 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
470 static const char* const caseList = "c.d\nc.e\na";
471 static const MatchCase subCases[] =
473 { "a", MatchCase::MATCH_CASE },
474 { "b", MatchCase::NO_MATCH },
475 { "a.b", MatchCase::NO_MATCH },
476 { "a.c", MatchCase::NO_MATCH },
477 { "a.d", MatchCase::NO_MATCH },
478 { "a.e", MatchCase::NO_MATCH },
479 { "c", MatchCase::MATCH_GROUP },
480 { "c.b", MatchCase::NO_MATCH },
481 { "c.d", MatchCase::MATCH_CASE },
482 { "c.e", MatchCase::MATCH_CASE },
484 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
487 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";
488 static const MatchCase subCases[] =
490 { "a", MatchCase::MATCH_GROUP },
491 { "b", MatchCase::NO_MATCH },
492 { "a.b", MatchCase::MATCH_GROUP },
493 { "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 },
495 addChild(new CaseListParserCase(m_testCtx, "long_name", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
498 static const char* const caseList =
504 static const MatchCase subCases[] =
506 { "a", MatchCase::MATCH_GROUP },
507 { "a.b", MatchCase::MATCH_GROUP },
508 { "a.b.c.d.e", MatchCase::MATCH_CASE },
509 { "a.b.c.d.g", MatchCase::MATCH_CASE },
510 { "x.y", MatchCase::MATCH_GROUP },
511 { "x.y.z", MatchCase::MATCH_CASE },
512 { "a.b.c.f", MatchCase::MATCH_CASE },
513 { "a.b.c.x", MatchCase::MATCH_CASE },
515 addChild(new CaseListParserCase(m_testCtx, "partial_prefix", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
518 static const char* const caseList =
521 static const MatchCase subCases[] =
523 { "a", MatchCase::MATCH_GROUP },
524 { "a.a", MatchCase::MATCH_GROUP },
525 { "a.b.c.d", MatchCase::MATCH_CASE },
526 { "a.b.c.d", MatchCase::MATCH_CASE },
528 addChild(new CaseListParserCase(m_testCtx, "reparenting", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
532 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", ""));
533 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n"));
534 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name", ".test"));
535 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name", "test."));
539 class CaseListParserTests : public tcu::TestCaseGroup
542 CaseListParserTests (tcu::TestContext& testCtx)
543 : tcu::TestCaseGroup(testCtx, "case_list_parser", "Test case list parser tests")
549 addChild(new TrieParserTests(m_testCtx));
550 addChild(new ListParserTests(m_testCtx));
554 inline deUint32 ulpDiff (float a, float b)
556 const deUint32 ab = tcu::Float32(a).bits();
557 const deUint32 bb = tcu::Float32(b).bits();
558 return de::max(ab, bb) - de::min(ab, bb);
562 inline tcu::Vector<deUint32, Size> ulpDiff (const tcu::Vector<float, Size>& a, const tcu::Vector<float, Size>& b)
564 tcu::Vector<deUint32, Size> res;
565 for (int ndx = 0; ndx < Size; ndx++)
566 res[ndx] = ulpDiff(a[ndx], b[ndx]);
570 class ConstantInterpolationTest : public tcu::TestCase
573 ConstantInterpolationTest (tcu::TestContext& testCtx)
574 : tcu::TestCase(testCtx, "const_interpolation", "Constant value interpolation")
576 const int supportedMsaaLevels[] = {1, 2, 4, 8, 16};
578 for (int msaaNdx = 0; msaaNdx < DE_LENGTH_OF_ARRAY(supportedMsaaLevels); msaaNdx++)
580 const int numSamples = supportedMsaaLevels[msaaNdx];
583 c.rtSize = tcu::IVec3(128, 128, numSamples);
584 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
585 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
586 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
587 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
588 m_cases.push_back(c);
593 c.rtSize = tcu::IVec3(128, 128, numSamples);
594 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
595 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
596 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
597 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
598 m_cases.push_back(c);
602 c.rtSize = tcu::IVec3(129, 113, numSamples);
603 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
604 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
605 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
606 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
607 m_cases.push_back(c);
611 c.rtSize = tcu::IVec3(107, 131, numSamples);
612 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
613 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
614 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
615 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
616 m_cases.push_back(c);
621 de::Random rnd(0x89423f);
622 for (int ndx = 0; ndx < 25; ndx++)
624 const float depth = rnd.getFloat()*2.0f - 1.0f;
627 c.rtSize.x() = rnd.getInt(16, 256);
628 c.rtSize.y() = rnd.getInt(16, 256);
629 c.rtSize.z() = rnd.choose<int>(DE_ARRAY_BEGIN(supportedMsaaLevels), DE_ARRAY_END(supportedMsaaLevels));
631 for (int vtxNdx = 0; vtxNdx < DE_LENGTH_OF_ARRAY(c.vtx); vtxNdx++)
633 c.vtx[vtxNdx].x() = rnd.getFloat()*2.0f - 1.0f;
634 c.vtx[vtxNdx].y() = rnd.getFloat()*2.0f - 1.0f;
635 c.vtx[vtxNdx].z() = depth;
636 c.vtx[vtxNdx].w() = 1.0f;
639 for (int compNdx = 0; compNdx < 4; compNdx++)
644 v = tcu::Float32(rnd.getUint32()).asFloat();
645 } while (deFloatIsInf(v) || deFloatIsNaN(v));
646 c.varying[compNdx] = v;
648 m_cases.push_back(c);
655 m_caseIter = m_cases.begin();
656 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All iterations passed");
659 IterateResult iterate (void)
662 tcu::ScopedLogSection section(m_testCtx.getLog(), "SubCase", "");
663 runCase(*m_caseIter);
665 return (++m_caseIter != m_cases.end()) ? CONTINUE : STOP;
671 tcu::IVec3 rtSize; // (width, height, samples)
676 void runCase (const SubCase& subCase)
680 const deUint32 maxColorUlpDiff = 2;
681 const deUint32 maxDepthUlpDiff = 0;
683 const int width = subCase.rtSize.x();
684 const int height = subCase.rtSize.y();
685 const int numSamples = subCase.rtSize.z();
686 const float zn = 0.0f;
687 const float zf = 1.0f;
689 TextureLevel interpolated (TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), numSamples, width, height);
690 TextureLevel depthStencil (TextureFormat(TextureFormat::DS, TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV), numSamples, width, height);
692 m_testCtx.getLog() << TestLog::Message
693 << "RT size (w, h, #samples) = " << subCase.rtSize << "\n"
694 << "vtx[0] = " << subCase.vtx[0] << "\n"
695 << "vtx[1] = " << subCase.vtx[1] << "\n"
696 << "vtx[2] = " << subCase.vtx[2] << "\n"
697 << "color = " << subCase.varying
698 << TestLog::EndMessage;
700 clear (interpolated.getAccess(), subCase.varying - Vec4(0.0f, 0.0f, 0.0f, 1.0f));
701 clearDepth (depthStencil.getAccess(), 0.0f);
702 clearStencil (depthStencil.getAccess(), 0);
705 class VtxShader : public rr::VertexShader
709 : rr::VertexShader(2, 1)
711 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
712 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
713 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
716 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
718 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
720 rr::readVertexAttrib(packets[packetNdx]->position, inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
721 packets[packetNdx]->outputs[0] = rr::readVertexAttribFloat(inputs[1], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
726 class FragShader : public rr::FragmentShader
730 : rr::FragmentShader(1, 1)
732 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
733 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
736 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
738 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
740 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
742 const tcu::Vec4 interp = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
743 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, interp);
749 const rr::Program program (&vtxShader, &fragShader);
751 const rr::MultisamplePixelBufferAccess colorAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(interpolated.getAccess());
752 const rr::MultisamplePixelBufferAccess dsAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess());
753 const rr::RenderTarget renderTarget (colorAccess, dsAccess, dsAccess);
754 const rr::VertexAttrib vertexAttribs[] =
756 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, 0, 0, subCase.vtx),
757 rr::VertexAttrib(subCase.varying)
759 rr::ViewportState viewport (colorAccess);
760 rr::RenderState state (viewport);
761 const rr::DrawCommand drawCmd (state, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), vertexAttribs, rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0));
762 const rr::Renderer renderer;
767 state.fragOps.depthTestEnabled = true;
768 state.fragOps.depthFunc = rr::TESTFUNC_ALWAYS;
769 state.fragOps.stencilTestEnabled = true;
770 state.fragOps.stencilStates[rr::FACETYPE_BACK].func = rr::TESTFUNC_ALWAYS;
771 state.fragOps.stencilStates[rr::FACETYPE_BACK].dpPass = rr::STENCILOP_INCR;
772 state.fragOps.stencilStates[rr::FACETYPE_FRONT] = state.fragOps.stencilStates[rr::FACETYPE_BACK];
774 renderer.draw(drawCmd);
777 // Verify interpolated values
779 TextureLevel resolvedColor (interpolated.getFormat(), width, height); // For debugging
780 TextureLevel resolvedDepthStencil (depthStencil.getFormat(), width, height); // For debugging
781 TextureLevel errorMask (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height);
782 const ConstPixelBufferAccess interpAccess = interpolated.getAccess();
783 const ConstPixelBufferAccess dsAccess = depthStencil.getAccess();
784 const PixelBufferAccess errorAccess = errorMask.getAccess();
785 int numCoveredSamples = 0;
786 int numFailedColorSamples = 0;
787 int numFailedDepthSamples = 0;
788 const bool verifyDepth = (subCase.vtx[0].z() == subCase.vtx[1].z()) &&
789 (subCase.vtx[1].z() == subCase.vtx[2].z());
790 const float refDepth = subCase.vtx[0].z()*(zf - zn)/2.0f + (zn + zf)/2.0f;
792 rr::resolveMultisampleColorBuffer(resolvedColor.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(interpolated.getAccess()));
793 rr::resolveMultisampleColorBuffer(resolvedDepthStencil.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess()));
794 clear(errorAccess, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
796 for (int y = 0; y < height; y++)
798 for (int x = 0; x < width; x++)
800 for (int sampleNdx = 0; sampleNdx < numSamples; sampleNdx++)
802 if (dsAccess.getPixStencil(sampleNdx, x, y) != 0)
804 const Vec4 color = interpAccess.getPixel(sampleNdx, x, y);
805 const UVec4 colorDiff = ulpDiff(color, subCase.varying);
806 const bool colorOk = boolAll(lessThanEqual(colorDiff, tcu::UVec4(maxColorUlpDiff)));
808 const float depth = dsAccess.getPixDepth(sampleNdx, x, y);
809 const deUint32 depthDiff = ulpDiff(depth, refDepth);
810 const bool depthOk = verifyDepth && (depthDiff <= maxDepthUlpDiff);
812 const int maxMsgs = 10;
814 numCoveredSamples += 1;
818 numFailedColorSamples += 1;
820 if (numFailedColorSamples <= maxMsgs)
821 m_testCtx.getLog() << TestLog::Message
822 << "FAIL: " << tcu::IVec3(x, y, sampleNdx)
823 << " color ulp diff = " << colorDiff
824 << TestLog::EndMessage;
828 numFailedDepthSamples += 1;
830 if (!colorOk || !depthOk)
831 errorAccess.setPixel(errorAccess.getPixel(x, y) + Vec4(1.0f, -1.0f, 0.0f, 0.0f) / float(numSamples-1), x, y);
837 m_testCtx.getLog() << TestLog::Image("ResolvedColor", "Resolved colorbuffer", resolvedColor)
838 << TestLog::Image("ResolvedDepthStencil", "Resolved depth- & stencilbuffer", resolvedDepthStencil);
840 if (numFailedColorSamples != 0 || numFailedDepthSamples != 0)
842 m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
844 if (numFailedColorSamples != 0)
845 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedColorSamples << " invalid color samples!" << TestLog::EndMessage;
847 if (numFailedDepthSamples != 0)
848 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedDepthSamples << " invalid depth samples!" << TestLog::EndMessage;
850 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
851 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid samples found");
854 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedColorSamples) << " / " << numCoveredSamples << " color samples passed" << TestLog::EndMessage;
855 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedDepthSamples) << " / " << numCoveredSamples << " depth samples passed" << TestLog::EndMessage;
859 vector<SubCase> m_cases;
860 vector<SubCase>::const_iterator m_caseIter;
863 class CommonFrameworkTests : public tcu::TestCaseGroup
866 CommonFrameworkTests (tcu::TestContext& testCtx)
867 : tcu::TestCaseGroup(testCtx, "common", "Tests for the common utility framework")
873 addChild(new SelfCheckCase(m_testCtx, "float_format","tcu::FloatFormat_selfTest()",
874 tcu::FloatFormat_selfTest));
875 addChild(new SelfCheckCase(m_testCtx, "either","tcu::Either_selfTest()",
876 tcu::Either_selfTest));
880 class ReferenceRendererTests : public tcu::TestCaseGroup
883 ReferenceRendererTests (tcu::TestContext& testCtx)
884 : tcu::TestCaseGroup(testCtx, "reference_renderer", "Reference renderer tests")
890 addChild(new ConstantInterpolationTest(m_testCtx));
896 FrameworkTests::FrameworkTests (tcu::TestContext& testCtx)
897 : tcu::TestCaseGroup(testCtx, "framework", "Miscellaneous framework tests")
901 FrameworkTests::~FrameworkTests (void)
905 void FrameworkTests::init (void)
907 addChild(new CommonFrameworkTests (m_testCtx));
908 addChild(new CaseListParserTests (m_testCtx));
909 addChild(new ReferenceRendererTests (m_testCtx));