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 "ditTextureFormatTests.hpp"
26 #include "ditAstcTests.hpp"
27 #include "ditVulkanTests.hpp"
29 #include "tcuFloatFormat.hpp"
30 #include "tcuEither.hpp"
31 #include "tcuTestLog.hpp"
32 #include "tcuCommandLine.hpp"
34 #include "rrRenderer.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuVectorUtil.hpp"
37 #include "tcuFloat.hpp"
39 #include "deRandom.hpp"
40 #include "deArrayUtil.hpp"
54 enum Expected { NO_MATCH, MATCH_GROUP, MATCH_CASE, EXPECTED_LAST };
60 const char* getMatchCaseExpectedDesc (MatchCase::Expected expected)
62 static const char* descs[] =
68 return de::getSizedArrayElement<MatchCase::EXPECTED_LAST>(descs, expected);
71 class CaseListParserCase : public tcu::TestCase
74 CaseListParserCase (tcu::TestContext& testCtx, const char* name, const char* caseList, const MatchCase* subCases, int numSubCases)
75 : tcu::TestCase (testCtx, name, "")
76 , m_caseList (caseList)
77 , m_subCases (subCases)
78 , m_numSubCases (numSubCases)
82 IterateResult iterate (void)
84 TestLog& log = m_testCtx.getLog();
85 tcu::CommandLine cmdLine;
88 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
98 if (!cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
99 TCU_FAIL("Failed to parse case list");
102 for (int subCaseNdx = 0; subCaseNdx < m_numSubCases; subCaseNdx++)
104 const MatchCase& curCase = m_subCases[subCaseNdx];
108 log << TestLog::Message << "Checking \"" << curCase.path << "\""
109 << ", expecting " << getMatchCaseExpectedDesc(curCase.expected)
110 << TestLog::EndMessage;
112 matchGroup = cmdLine.checkTestGroupName(curCase.path);
113 matchCase = cmdLine.checkTestCaseName(curCase.path);
115 if ((matchGroup == (curCase.expected == MatchCase::MATCH_GROUP)) &&
116 (matchCase == (curCase.expected == MatchCase::MATCH_CASE)))
118 log << TestLog::Message << " pass" << TestLog::EndMessage;
122 log << TestLog::Message << " FAIL!" << TestLog::EndMessage;
125 m_testCtx.setTestResult((numPass == m_numSubCases) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
126 (numPass == m_numSubCases) ? "All passed" : "Unexpected match result");
132 const char* const m_caseList;
133 const MatchCase* const m_subCases;
134 const int m_numSubCases;
137 class NegativeCaseListCase : public tcu::TestCase
140 NegativeCaseListCase (tcu::TestContext& testCtx, const char* name, const char* caseList)
141 : tcu::TestCase (testCtx, name, "")
142 , m_caseList (caseList)
146 IterateResult iterate (void)
148 TestLog& log = m_testCtx.getLog();
149 tcu::CommandLine cmdLine;
151 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
161 if (cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
162 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Parsing passed, should have failed");
164 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Parsing failed as expected");
171 const char* const m_caseList;
174 class TrieParserTests : public tcu::TestCaseGroup
177 TrieParserTests (tcu::TestContext& testCtx)
178 : tcu::TestCaseGroup(testCtx, "trie", "Test case trie parser tests")
185 static const char* const caseList = "{test}";
186 static const MatchCase subCases[] =
188 { "test", MatchCase::MATCH_CASE },
189 { "test.cd", MatchCase::NO_MATCH },
191 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
194 static const char* const caseList = "{a{b}}";
195 static const MatchCase subCases[] =
197 { "a", MatchCase::MATCH_GROUP },
198 { "b", MatchCase::NO_MATCH },
199 { "a.b", MatchCase::MATCH_CASE },
200 { "a.a", MatchCase::NO_MATCH },
202 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
205 static const char* const caseList = "{a{b,c}}";
206 static const MatchCase subCases[] =
208 { "a", MatchCase::MATCH_GROUP },
209 { "b", MatchCase::NO_MATCH },
210 { "a.b", MatchCase::MATCH_CASE },
211 { "a.a", MatchCase::NO_MATCH },
212 { "a.c", MatchCase::MATCH_CASE },
214 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
217 static const char* const caseList = "{a{b},c{d,e}}";
218 static const MatchCase subCases[] =
220 { "a", MatchCase::MATCH_GROUP },
221 { "b", MatchCase::NO_MATCH },
222 { "a.b", MatchCase::MATCH_CASE },
223 { "a.c", MatchCase::NO_MATCH },
224 { "a.d", MatchCase::NO_MATCH },
225 { "a.e", MatchCase::NO_MATCH },
226 { "c", MatchCase::MATCH_GROUP },
227 { "c.b", MatchCase::NO_MATCH },
228 { "c.d", MatchCase::MATCH_CASE },
229 { "c.e", MatchCase::MATCH_CASE },
231 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
234 static const char* const caseList = "{a,c{d,e}}";
235 static const MatchCase subCases[] =
237 { "a", MatchCase::MATCH_CASE },
238 { "b", MatchCase::NO_MATCH },
239 { "a.b", MatchCase::NO_MATCH },
240 { "a.c", MatchCase::NO_MATCH },
241 { "a.d", MatchCase::NO_MATCH },
242 { "a.e", MatchCase::NO_MATCH },
243 { "c", MatchCase::MATCH_GROUP },
244 { "c.b", MatchCase::NO_MATCH },
245 { "c.d", MatchCase::MATCH_CASE },
246 { "c.e", MatchCase::MATCH_CASE },
248 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
251 static const char* const caseList = "{c{d,e},a}";
252 static const MatchCase subCases[] =
254 { "a", MatchCase::MATCH_CASE },
255 { "b", MatchCase::NO_MATCH },
256 { "a.b", MatchCase::NO_MATCH },
257 { "a.c", MatchCase::NO_MATCH },
258 { "a.d", MatchCase::NO_MATCH },
259 { "a.e", MatchCase::NO_MATCH },
260 { "c", MatchCase::MATCH_GROUP },
261 { "c.b", MatchCase::NO_MATCH },
262 { "c.d", MatchCase::MATCH_CASE },
263 { "c.e", MatchCase::MATCH_CASE },
265 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
268 static const char* const caseList = "{test}\r";
269 static const MatchCase subCases[] =
271 { "test", MatchCase::MATCH_CASE },
272 { "test.cd", MatchCase::NO_MATCH },
274 addChild(new CaseListParserCase(m_testCtx, "trailing_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
277 static const char* const caseList = "{test}\n";
278 static const MatchCase subCases[] =
280 { "test", MatchCase::MATCH_CASE },
281 { "test.cd", MatchCase::NO_MATCH },
283 addChild(new CaseListParserCase(m_testCtx, "trailing_lf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
286 static const char* const caseList = "{test}\r\n";
287 static const MatchCase subCases[] =
289 { "test", MatchCase::MATCH_CASE },
290 { "test.cd", MatchCase::NO_MATCH },
292 addChild(new CaseListParserCase(m_testCtx, "trailing_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
296 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", ""));
297 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n"));
298 addChild(new NegativeCaseListCase(m_testCtx, "empty_root", "{}"));
299 addChild(new NegativeCaseListCase(m_testCtx, "empty_group", "{test{}}"));
300 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_1", "{{}}"));
301 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_2", "{{test}}"));
302 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_1", "{"));
303 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_2", "{test"));
304 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_3", "{test,"));
305 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_4", "{test{a}"));
306 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_5", "{a,b"));
307 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_1", "{test{"));
308 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_2", "{test{a"));
309 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_3", "{test{a,"));
310 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_4", "{test{a,b"));
311 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_1", "{a,,b}"));
312 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_2", "{,b}"));
313 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_3", "{a,}"));
314 addChild(new NegativeCaseListCase(m_testCtx, "no_separator", "{a{b}c}"));
315 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_1", "{a.b}"));
316 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_2", "{a[]}"));
317 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_1", "{a}}"));
318 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_2", "{a}x"));
319 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_1", "{\na}"));
320 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_2", "{a\n,b}"));
321 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_3", "{a,\nb}"));
322 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_4", "{a{b\n}}"));
323 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_5", "{a{b}\n}"));
327 class ListParserTests : public tcu::TestCaseGroup
330 ListParserTests (tcu::TestContext& testCtx)
331 : tcu::TestCaseGroup(testCtx, "list", "Test case list parser tests")
338 static const char* const caseList = "test";
339 static const MatchCase subCases[] =
341 { "test", MatchCase::MATCH_CASE },
342 { "test.cd", MatchCase::NO_MATCH },
344 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
347 static const char* const caseList = "a.b";
348 static const MatchCase subCases[] =
350 { "a", MatchCase::MATCH_GROUP },
351 { "b", MatchCase::NO_MATCH },
352 { "a.b", MatchCase::MATCH_CASE },
353 { "a.a", MatchCase::NO_MATCH },
355 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
358 static const char* const caseList = "a.b\na.c";
359 static const MatchCase subCases[] =
361 { "a", MatchCase::MATCH_GROUP },
362 { "b", MatchCase::NO_MATCH },
363 { "a.b", MatchCase::MATCH_CASE },
364 { "a.a", MatchCase::NO_MATCH },
365 { "a.c", MatchCase::MATCH_CASE },
367 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
370 static const char* const caseList = "a.b\na.c";
371 static const MatchCase subCases[] =
373 { "a", MatchCase::MATCH_GROUP },
374 { "b", MatchCase::NO_MATCH },
375 { "a.b", MatchCase::MATCH_CASE },
376 { "a.a", MatchCase::NO_MATCH },
377 { "a.c", MatchCase::MATCH_CASE },
379 addChild(new CaseListParserCase(m_testCtx, "separator_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
382 static const char* const caseList = "a.b\ra.c";
383 static const MatchCase subCases[] =
385 { "a", MatchCase::MATCH_GROUP },
386 { "b", MatchCase::NO_MATCH },
387 { "a.b", MatchCase::MATCH_CASE },
388 { "a.a", MatchCase::NO_MATCH },
389 { "a.c", MatchCase::MATCH_CASE },
391 addChild(new CaseListParserCase(m_testCtx, "separator_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
394 static const char* const caseList = "a.b\r\na.c";
395 static const MatchCase subCases[] =
397 { "a", MatchCase::MATCH_GROUP },
398 { "b", MatchCase::NO_MATCH },
399 { "a.b", MatchCase::MATCH_CASE },
400 { "a.a", MatchCase::NO_MATCH },
401 { "a.c", MatchCase::MATCH_CASE },
403 addChild(new CaseListParserCase(m_testCtx, "separator_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
406 static const char* const caseList = "a.b\na.c\n";
407 static const MatchCase subCases[] =
409 { "a", MatchCase::MATCH_GROUP },
410 { "b", MatchCase::NO_MATCH },
411 { "a.b", MatchCase::MATCH_CASE },
412 { "a.a", MatchCase::NO_MATCH },
413 { "a.c", MatchCase::MATCH_CASE },
415 addChild(new CaseListParserCase(m_testCtx, "end_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
418 static const char* const caseList = "a.b\na.c\r";
419 static const MatchCase subCases[] =
421 { "a", MatchCase::MATCH_GROUP },
422 { "b", MatchCase::NO_MATCH },
423 { "a.b", MatchCase::MATCH_CASE },
424 { "a.a", MatchCase::NO_MATCH },
425 { "a.c", MatchCase::MATCH_CASE },
427 addChild(new CaseListParserCase(m_testCtx, "end_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
430 static const char* const caseList = "a.b\na.c\r\n";
431 static const MatchCase subCases[] =
433 { "a", MatchCase::MATCH_GROUP },
434 { "b", MatchCase::NO_MATCH },
435 { "a.b", MatchCase::MATCH_CASE },
436 { "a.a", MatchCase::NO_MATCH },
437 { "a.c", MatchCase::MATCH_CASE },
439 addChild(new CaseListParserCase(m_testCtx, "end_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
442 static const char* const caseList = "a.b\nc.d\nc.e";
443 static const MatchCase subCases[] =
445 { "a", MatchCase::MATCH_GROUP },
446 { "b", MatchCase::NO_MATCH },
447 { "a.b", MatchCase::MATCH_CASE },
448 { "a.c", MatchCase::NO_MATCH },
449 { "a.d", MatchCase::NO_MATCH },
450 { "a.e", MatchCase::NO_MATCH },
451 { "c", MatchCase::MATCH_GROUP },
452 { "c.b", MatchCase::NO_MATCH },
453 { "c.d", MatchCase::MATCH_CASE },
454 { "c.e", MatchCase::MATCH_CASE },
456 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
459 static const char* const caseList = "a\nc.d\nc.e";
460 static const MatchCase subCases[] =
462 { "a", MatchCase::MATCH_CASE },
463 { "b", MatchCase::NO_MATCH },
464 { "a.b", MatchCase::NO_MATCH },
465 { "a.c", MatchCase::NO_MATCH },
466 { "a.d", MatchCase::NO_MATCH },
467 { "a.e", MatchCase::NO_MATCH },
468 { "c", MatchCase::MATCH_GROUP },
469 { "c.b", MatchCase::NO_MATCH },
470 { "c.d", MatchCase::MATCH_CASE },
471 { "c.e", MatchCase::MATCH_CASE },
473 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
476 static const char* const caseList = "c.d\nc.e\na";
477 static const MatchCase subCases[] =
479 { "a", MatchCase::MATCH_CASE },
480 { "b", MatchCase::NO_MATCH },
481 { "a.b", MatchCase::NO_MATCH },
482 { "a.c", MatchCase::NO_MATCH },
483 { "a.d", MatchCase::NO_MATCH },
484 { "a.e", MatchCase::NO_MATCH },
485 { "c", MatchCase::MATCH_GROUP },
486 { "c.b", MatchCase::NO_MATCH },
487 { "c.d", MatchCase::MATCH_CASE },
488 { "c.e", MatchCase::MATCH_CASE },
490 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
493 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";
494 static const MatchCase subCases[] =
496 { "a", MatchCase::MATCH_GROUP },
497 { "b", MatchCase::NO_MATCH },
498 { "a.b", MatchCase::MATCH_GROUP },
499 { "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 },
501 addChild(new CaseListParserCase(m_testCtx, "long_name", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
504 static const char* const caseList =
510 static const MatchCase subCases[] =
512 { "a", MatchCase::MATCH_GROUP },
513 { "a.b", MatchCase::MATCH_GROUP },
514 { "a.b.c.d.e", MatchCase::MATCH_CASE },
515 { "a.b.c.d.g", MatchCase::MATCH_CASE },
516 { "x.y", MatchCase::MATCH_GROUP },
517 { "x.y.z", MatchCase::MATCH_CASE },
518 { "a.b.c.f", MatchCase::MATCH_CASE },
519 { "a.b.c.x", MatchCase::MATCH_CASE },
521 addChild(new CaseListParserCase(m_testCtx, "partial_prefix", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
524 static const char* const caseList =
527 static const MatchCase subCases[] =
529 { "a", MatchCase::MATCH_GROUP },
530 { "a.a", MatchCase::MATCH_GROUP },
531 { "a.b.c.d", MatchCase::MATCH_CASE },
532 { "a.b.c.d", MatchCase::MATCH_CASE },
534 addChild(new CaseListParserCase(m_testCtx, "reparenting", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
538 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", ""));
539 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n"));
540 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name", ".test"));
541 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name", "test."));
545 class CaseListParserTests : public tcu::TestCaseGroup
548 CaseListParserTests (tcu::TestContext& testCtx)
549 : tcu::TestCaseGroup(testCtx, "case_list_parser", "Test case list parser tests")
555 addChild(new TrieParserTests(m_testCtx));
556 addChild(new ListParserTests(m_testCtx));
560 inline deUint32 ulpDiff (float a, float b)
562 const deUint32 ab = tcu::Float32(a).bits();
563 const deUint32 bb = tcu::Float32(b).bits();
564 return de::max(ab, bb) - de::min(ab, bb);
568 inline tcu::Vector<deUint32, Size> ulpDiff (const tcu::Vector<float, Size>& a, const tcu::Vector<float, Size>& b)
570 tcu::Vector<deUint32, Size> res;
571 for (int ndx = 0; ndx < Size; ndx++)
572 res[ndx] = ulpDiff(a[ndx], b[ndx]);
576 class ConstantInterpolationTest : public tcu::TestCase
579 ConstantInterpolationTest (tcu::TestContext& testCtx)
580 : tcu::TestCase(testCtx, "const_interpolation", "Constant value interpolation")
582 const int supportedMsaaLevels[] = {1, 2, 4, 8, 16};
584 for (int msaaNdx = 0; msaaNdx < DE_LENGTH_OF_ARRAY(supportedMsaaLevels); msaaNdx++)
586 const int numSamples = supportedMsaaLevels[msaaNdx];
589 c.rtSize = tcu::IVec3(128, 128, numSamples);
590 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
591 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
592 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
593 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
594 m_cases.push_back(c);
599 c.rtSize = tcu::IVec3(128, 128, numSamples);
600 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
601 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
602 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
603 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
604 m_cases.push_back(c);
608 c.rtSize = tcu::IVec3(129, 113, numSamples);
609 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
610 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
611 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
612 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
613 m_cases.push_back(c);
617 c.rtSize = tcu::IVec3(107, 131, numSamples);
618 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
619 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
620 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
621 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
622 m_cases.push_back(c);
627 de::Random rnd(0x89423f);
628 for (int ndx = 0; ndx < 25; ndx++)
630 const float depth = rnd.getFloat()*2.0f - 1.0f;
633 c.rtSize.x() = rnd.getInt(16, 256);
634 c.rtSize.y() = rnd.getInt(16, 256);
635 c.rtSize.z() = rnd.choose<int>(DE_ARRAY_BEGIN(supportedMsaaLevels), DE_ARRAY_END(supportedMsaaLevels));
637 for (int vtxNdx = 0; vtxNdx < DE_LENGTH_OF_ARRAY(c.vtx); vtxNdx++)
639 c.vtx[vtxNdx].x() = rnd.getFloat()*2.0f - 1.0f;
640 c.vtx[vtxNdx].y() = rnd.getFloat()*2.0f - 1.0f;
641 c.vtx[vtxNdx].z() = depth;
642 c.vtx[vtxNdx].w() = 1.0f;
645 for (int compNdx = 0; compNdx < 4; compNdx++)
650 v = tcu::Float32(rnd.getUint32()).asFloat();
651 } while (deFloatIsInf(v) || deFloatIsNaN(v));
652 c.varying[compNdx] = v;
654 m_cases.push_back(c);
661 m_caseIter = m_cases.begin();
662 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All iterations passed");
665 IterateResult iterate (void)
668 tcu::ScopedLogSection section(m_testCtx.getLog(), "SubCase", "");
669 runCase(*m_caseIter);
671 return (++m_caseIter != m_cases.end()) ? CONTINUE : STOP;
677 tcu::IVec3 rtSize; // (width, height, samples)
682 void runCase (const SubCase& subCase)
686 const deUint32 maxColorUlpDiff = 2;
687 const deUint32 maxDepthUlpDiff = 0;
689 const int width = subCase.rtSize.x();
690 const int height = subCase.rtSize.y();
691 const int numSamples = subCase.rtSize.z();
692 const float zn = 0.0f;
693 const float zf = 1.0f;
695 TextureLevel interpolated (TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), numSamples, width, height);
696 TextureLevel depthStencil (TextureFormat(TextureFormat::DS, TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV), numSamples, width, height);
698 m_testCtx.getLog() << TestLog::Message
699 << "RT size (w, h, #samples) = " << subCase.rtSize << "\n"
700 << "vtx[0] = " << subCase.vtx[0] << "\n"
701 << "vtx[1] = " << subCase.vtx[1] << "\n"
702 << "vtx[2] = " << subCase.vtx[2] << "\n"
703 << "color = " << subCase.varying
704 << TestLog::EndMessage;
706 clear (interpolated.getAccess(), subCase.varying - Vec4(0.0f, 0.0f, 0.0f, 1.0f));
707 clearDepth (depthStencil.getAccess(), 0.0f);
708 clearStencil (depthStencil.getAccess(), 0);
711 class VtxShader : public rr::VertexShader
715 : rr::VertexShader(2, 1)
717 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
718 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
719 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
722 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
724 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
726 rr::readVertexAttrib(packets[packetNdx]->position, inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
727 packets[packetNdx]->outputs[0] = rr::readVertexAttribFloat(inputs[1], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
732 class FragShader : public rr::FragmentShader
736 : rr::FragmentShader(1, 1)
738 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
739 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
742 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
744 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
746 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
748 const tcu::Vec4 interp = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
749 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, interp);
755 const rr::Program program (&vtxShader, &fragShader);
757 const rr::MultisamplePixelBufferAccess colorAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(interpolated.getAccess());
758 const rr::MultisamplePixelBufferAccess dsAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess());
759 const rr::RenderTarget renderTarget (colorAccess, dsAccess, dsAccess);
760 const rr::VertexAttrib vertexAttribs[] =
762 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, 0, 0, subCase.vtx),
763 rr::VertexAttrib(subCase.varying)
765 rr::ViewportState viewport (colorAccess);
766 rr::RenderState state (viewport);
767 const rr::DrawCommand drawCmd (state, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), vertexAttribs, rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0));
768 const rr::Renderer renderer;
773 state.fragOps.depthTestEnabled = true;
774 state.fragOps.depthFunc = rr::TESTFUNC_ALWAYS;
775 state.fragOps.stencilTestEnabled = true;
776 state.fragOps.stencilStates[rr::FACETYPE_BACK].func = rr::TESTFUNC_ALWAYS;
777 state.fragOps.stencilStates[rr::FACETYPE_BACK].dpPass = rr::STENCILOP_INCR;
778 state.fragOps.stencilStates[rr::FACETYPE_FRONT] = state.fragOps.stencilStates[rr::FACETYPE_BACK];
780 renderer.draw(drawCmd);
783 // Verify interpolated values
785 TextureLevel resolvedColor (interpolated.getFormat(), width, height); // For debugging
786 TextureLevel resolvedDepthStencil (depthStencil.getFormat(), width, height); // For debugging
787 TextureLevel errorMask (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height);
788 const ConstPixelBufferAccess interpAccess = interpolated.getAccess();
789 const ConstPixelBufferAccess dsAccess = depthStencil.getAccess();
790 const PixelBufferAccess errorAccess = errorMask.getAccess();
791 int numCoveredSamples = 0;
792 int numFailedColorSamples = 0;
793 int numFailedDepthSamples = 0;
794 const bool verifyDepth = (subCase.vtx[0].z() == subCase.vtx[1].z()) &&
795 (subCase.vtx[1].z() == subCase.vtx[2].z());
796 const float refDepth = subCase.vtx[0].z()*(zf - zn)/2.0f + (zn + zf)/2.0f;
798 rr::resolveMultisampleBuffer(resolvedColor.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(interpolated.getAccess()));
799 rr::resolveMultisampleBuffer(resolvedDepthStencil.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess()));
800 clear(errorAccess, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
802 for (int y = 0; y < height; y++)
804 for (int x = 0; x < width; x++)
806 for (int sampleNdx = 0; sampleNdx < numSamples; sampleNdx++)
808 if (dsAccess.getPixStencil(sampleNdx, x, y) != 0)
810 const Vec4 color = interpAccess.getPixel(sampleNdx, x, y);
811 const UVec4 colorDiff = ulpDiff(color, subCase.varying);
812 const bool colorOk = boolAll(lessThanEqual(colorDiff, tcu::UVec4(maxColorUlpDiff)));
814 const float depth = dsAccess.getPixDepth(sampleNdx, x, y);
815 const deUint32 depthDiff = ulpDiff(depth, refDepth);
816 const bool depthOk = verifyDepth && (depthDiff <= maxDepthUlpDiff);
818 const int maxMsgs = 10;
820 numCoveredSamples += 1;
824 numFailedColorSamples += 1;
826 if (numFailedColorSamples <= maxMsgs)
827 m_testCtx.getLog() << TestLog::Message
828 << "FAIL: " << tcu::IVec3(x, y, sampleNdx)
829 << " color ulp diff = " << colorDiff
830 << TestLog::EndMessage;
834 numFailedDepthSamples += 1;
836 if (!colorOk || !depthOk)
837 errorAccess.setPixel(errorAccess.getPixel(x, y) + Vec4(1.0f, -1.0f, 0.0f, 0.0f) / float(numSamples-1), x, y);
843 m_testCtx.getLog() << TestLog::Image("ResolvedColor", "Resolved colorbuffer", resolvedColor)
844 << TestLog::Image("ResolvedDepthStencil", "Resolved depth- & stencilbuffer", resolvedDepthStencil);
846 if (numFailedColorSamples != 0 || numFailedDepthSamples != 0)
848 m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
850 if (numFailedColorSamples != 0)
851 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedColorSamples << " invalid color samples!" << TestLog::EndMessage;
853 if (numFailedDepthSamples != 0)
854 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedDepthSamples << " invalid depth samples!" << TestLog::EndMessage;
856 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
857 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid samples found");
860 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedColorSamples) << " / " << numCoveredSamples << " color samples passed" << TestLog::EndMessage;
861 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedDepthSamples) << " / " << numCoveredSamples << " depth samples passed" << TestLog::EndMessage;
865 vector<SubCase> m_cases;
866 vector<SubCase>::const_iterator m_caseIter;
869 class CommonFrameworkTests : public tcu::TestCaseGroup
872 CommonFrameworkTests (tcu::TestContext& testCtx)
873 : tcu::TestCaseGroup(testCtx, "common", "Tests for the common utility framework")
879 addChild(new SelfCheckCase(m_testCtx, "float_format","tcu::FloatFormat_selfTest()",
880 tcu::FloatFormat_selfTest));
881 addChild(new SelfCheckCase(m_testCtx, "either","tcu::Either_selfTest()",
882 tcu::Either_selfTest));
886 class ReferenceRendererTests : public tcu::TestCaseGroup
889 ReferenceRendererTests (tcu::TestContext& testCtx)
890 : tcu::TestCaseGroup(testCtx, "reference_renderer", "Reference renderer tests")
896 addChild(new ConstantInterpolationTest(m_testCtx));
902 FrameworkTests::FrameworkTests (tcu::TestContext& testCtx)
903 : tcu::TestCaseGroup(testCtx, "framework", "Miscellaneous framework tests")
907 FrameworkTests::~FrameworkTests (void)
911 void FrameworkTests::init (void)
913 addChild(new CommonFrameworkTests (m_testCtx));
914 addChild(new CaseListParserTests (m_testCtx));
915 addChild(new ReferenceRendererTests (m_testCtx));
916 addChild(createTextureFormatTests (m_testCtx));
917 addChild(createAstcTests (m_testCtx));
918 addChild(createVulkanTests (m_testCtx));