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 "ditVulkanTests.hpp"
28 #include "tcuFloatFormat.hpp"
29 #include "tcuEither.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuCommandLine.hpp"
33 #include "rrRenderer.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "tcuVectorUtil.hpp"
36 #include "tcuFloat.hpp"
38 #include "deRandom.hpp"
39 #include "deArrayUtil.hpp"
53 enum Expected { NO_MATCH, MATCH_GROUP, MATCH_CASE, EXPECTED_LAST };
59 const char* getMatchCaseExpectedDesc (MatchCase::Expected expected)
61 static const char* descs[] =
67 return de::getSizedArrayElement<MatchCase::EXPECTED_LAST>(descs, expected);
70 class CaseListParserCase : public tcu::TestCase
73 CaseListParserCase (tcu::TestContext& testCtx, const char* name, const char* caseList, const MatchCase* subCases, int numSubCases)
74 : tcu::TestCase (testCtx, name, "")
75 , m_caseList (caseList)
76 , m_subCases (subCases)
77 , m_numSubCases (numSubCases)
81 IterateResult iterate (void)
83 TestLog& log = m_testCtx.getLog();
84 tcu::CommandLine cmdLine;
87 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
97 if (!cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
98 TCU_FAIL("Failed to parse case list");
101 for (int subCaseNdx = 0; subCaseNdx < m_numSubCases; subCaseNdx++)
103 const MatchCase& curCase = m_subCases[subCaseNdx];
107 log << TestLog::Message << "Checking \"" << curCase.path << "\""
108 << ", expecting " << getMatchCaseExpectedDesc(curCase.expected)
109 << TestLog::EndMessage;
111 matchGroup = cmdLine.checkTestGroupName(curCase.path);
112 matchCase = cmdLine.checkTestCaseName(curCase.path);
114 if ((matchGroup == (curCase.expected == MatchCase::MATCH_GROUP)) &&
115 (matchCase == (curCase.expected == MatchCase::MATCH_CASE)))
117 log << TestLog::Message << " pass" << TestLog::EndMessage;
121 log << TestLog::Message << " FAIL!" << TestLog::EndMessage;
124 m_testCtx.setTestResult((numPass == m_numSubCases) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
125 (numPass == m_numSubCases) ? "All passed" : "Unexpected match result");
131 const char* const m_caseList;
132 const MatchCase* const m_subCases;
133 const int m_numSubCases;
136 class NegativeCaseListCase : public tcu::TestCase
139 NegativeCaseListCase (tcu::TestContext& testCtx, const char* name, const char* caseList)
140 : tcu::TestCase (testCtx, name, "")
141 , m_caseList (caseList)
145 IterateResult iterate (void)
147 TestLog& log = m_testCtx.getLog();
148 tcu::CommandLine cmdLine;
150 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage;
160 if (cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv))
161 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Parsing passed, should have failed");
163 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Parsing failed as expected");
170 const char* const m_caseList;
173 class TrieParserTests : public tcu::TestCaseGroup
176 TrieParserTests (tcu::TestContext& testCtx)
177 : tcu::TestCaseGroup(testCtx, "trie", "Test case trie parser tests")
184 static const char* const caseList = "{test}";
185 static const MatchCase subCases[] =
187 { "test", MatchCase::MATCH_CASE },
188 { "test.cd", MatchCase::NO_MATCH },
190 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
193 static const char* const caseList = "{a{b}}";
194 static const MatchCase subCases[] =
196 { "a", MatchCase::MATCH_GROUP },
197 { "b", MatchCase::NO_MATCH },
198 { "a.b", MatchCase::MATCH_CASE },
199 { "a.a", MatchCase::NO_MATCH },
201 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
204 static const char* const caseList = "{a{b,c}}";
205 static const MatchCase subCases[] =
207 { "a", MatchCase::MATCH_GROUP },
208 { "b", MatchCase::NO_MATCH },
209 { "a.b", MatchCase::MATCH_CASE },
210 { "a.a", MatchCase::NO_MATCH },
211 { "a.c", MatchCase::MATCH_CASE },
213 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
216 static const char* const caseList = "{a{b},c{d,e}}";
217 static const MatchCase subCases[] =
219 { "a", MatchCase::MATCH_GROUP },
220 { "b", MatchCase::NO_MATCH },
221 { "a.b", MatchCase::MATCH_CASE },
222 { "a.c", MatchCase::NO_MATCH },
223 { "a.d", MatchCase::NO_MATCH },
224 { "a.e", MatchCase::NO_MATCH },
225 { "c", MatchCase::MATCH_GROUP },
226 { "c.b", MatchCase::NO_MATCH },
227 { "c.d", MatchCase::MATCH_CASE },
228 { "c.e", MatchCase::MATCH_CASE },
230 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
233 static const char* const caseList = "{a,c{d,e}}";
234 static const MatchCase subCases[] =
236 { "a", MatchCase::MATCH_CASE },
237 { "b", MatchCase::NO_MATCH },
238 { "a.b", MatchCase::NO_MATCH },
239 { "a.c", MatchCase::NO_MATCH },
240 { "a.d", MatchCase::NO_MATCH },
241 { "a.e", MatchCase::NO_MATCH },
242 { "c", MatchCase::MATCH_GROUP },
243 { "c.b", MatchCase::NO_MATCH },
244 { "c.d", MatchCase::MATCH_CASE },
245 { "c.e", MatchCase::MATCH_CASE },
247 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
250 static const char* const caseList = "{c{d,e},a}";
251 static const MatchCase subCases[] =
253 { "a", MatchCase::MATCH_CASE },
254 { "b", MatchCase::NO_MATCH },
255 { "a.b", MatchCase::NO_MATCH },
256 { "a.c", MatchCase::NO_MATCH },
257 { "a.d", MatchCase::NO_MATCH },
258 { "a.e", MatchCase::NO_MATCH },
259 { "c", MatchCase::MATCH_GROUP },
260 { "c.b", MatchCase::NO_MATCH },
261 { "c.d", MatchCase::MATCH_CASE },
262 { "c.e", MatchCase::MATCH_CASE },
264 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
267 static const char* const caseList = "{test}\r";
268 static const MatchCase subCases[] =
270 { "test", MatchCase::MATCH_CASE },
271 { "test.cd", MatchCase::NO_MATCH },
273 addChild(new CaseListParserCase(m_testCtx, "trailing_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
276 static const char* const caseList = "{test}\n";
277 static const MatchCase subCases[] =
279 { "test", MatchCase::MATCH_CASE },
280 { "test.cd", MatchCase::NO_MATCH },
282 addChild(new CaseListParserCase(m_testCtx, "trailing_lf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
285 static const char* const caseList = "{test}\r\n";
286 static const MatchCase subCases[] =
288 { "test", MatchCase::MATCH_CASE },
289 { "test.cd", MatchCase::NO_MATCH },
291 addChild(new CaseListParserCase(m_testCtx, "trailing_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
295 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", ""));
296 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n"));
297 addChild(new NegativeCaseListCase(m_testCtx, "empty_root", "{}"));
298 addChild(new NegativeCaseListCase(m_testCtx, "empty_group", "{test{}}"));
299 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_1", "{{}}"));
300 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_2", "{{test}}"));
301 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_1", "{"));
302 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_2", "{test"));
303 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_3", "{test,"));
304 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_4", "{test{a}"));
305 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_5", "{a,b"));
306 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_1", "{test{"));
307 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_2", "{test{a"));
308 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_3", "{test{a,"));
309 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_4", "{test{a,b"));
310 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_1", "{a,,b}"));
311 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_2", "{,b}"));
312 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_3", "{a,}"));
313 addChild(new NegativeCaseListCase(m_testCtx, "no_separator", "{a{b}c}"));
314 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_1", "{a.b}"));
315 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_2", "{a[]}"));
316 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_1", "{a}}"));
317 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_2", "{a}x"));
318 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_1", "{\na}"));
319 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_2", "{a\n,b}"));
320 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_3", "{a,\nb}"));
321 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_4", "{a{b\n}}"));
322 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_5", "{a{b}\n}"));
326 class ListParserTests : public tcu::TestCaseGroup
329 ListParserTests (tcu::TestContext& testCtx)
330 : tcu::TestCaseGroup(testCtx, "list", "Test case list parser tests")
337 static const char* const caseList = "test";
338 static const MatchCase subCases[] =
340 { "test", MatchCase::MATCH_CASE },
341 { "test.cd", MatchCase::NO_MATCH },
343 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
346 static const char* const caseList = "a.b";
347 static const MatchCase subCases[] =
349 { "a", MatchCase::MATCH_GROUP },
350 { "b", MatchCase::NO_MATCH },
351 { "a.b", MatchCase::MATCH_CASE },
352 { "a.a", MatchCase::NO_MATCH },
354 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
357 static const char* const caseList = "a.b\na.c";
358 static const MatchCase subCases[] =
360 { "a", MatchCase::MATCH_GROUP },
361 { "b", MatchCase::NO_MATCH },
362 { "a.b", MatchCase::MATCH_CASE },
363 { "a.a", MatchCase::NO_MATCH },
364 { "a.c", MatchCase::MATCH_CASE },
366 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
369 static const char* const caseList = "a.b\na.c";
370 static const MatchCase subCases[] =
372 { "a", MatchCase::MATCH_GROUP },
373 { "b", MatchCase::NO_MATCH },
374 { "a.b", MatchCase::MATCH_CASE },
375 { "a.a", MatchCase::NO_MATCH },
376 { "a.c", MatchCase::MATCH_CASE },
378 addChild(new CaseListParserCase(m_testCtx, "separator_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
381 static const char* const caseList = "a.b\ra.c";
382 static const MatchCase subCases[] =
384 { "a", MatchCase::MATCH_GROUP },
385 { "b", MatchCase::NO_MATCH },
386 { "a.b", MatchCase::MATCH_CASE },
387 { "a.a", MatchCase::NO_MATCH },
388 { "a.c", MatchCase::MATCH_CASE },
390 addChild(new CaseListParserCase(m_testCtx, "separator_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
393 static const char* const caseList = "a.b\r\na.c";
394 static const MatchCase subCases[] =
396 { "a", MatchCase::MATCH_GROUP },
397 { "b", MatchCase::NO_MATCH },
398 { "a.b", MatchCase::MATCH_CASE },
399 { "a.a", MatchCase::NO_MATCH },
400 { "a.c", MatchCase::MATCH_CASE },
402 addChild(new CaseListParserCase(m_testCtx, "separator_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
405 static const char* const caseList = "a.b\na.c\n";
406 static const MatchCase subCases[] =
408 { "a", MatchCase::MATCH_GROUP },
409 { "b", MatchCase::NO_MATCH },
410 { "a.b", MatchCase::MATCH_CASE },
411 { "a.a", MatchCase::NO_MATCH },
412 { "a.c", MatchCase::MATCH_CASE },
414 addChild(new CaseListParserCase(m_testCtx, "end_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
417 static const char* const caseList = "a.b\na.c\r";
418 static const MatchCase subCases[] =
420 { "a", MatchCase::MATCH_GROUP },
421 { "b", MatchCase::NO_MATCH },
422 { "a.b", MatchCase::MATCH_CASE },
423 { "a.a", MatchCase::NO_MATCH },
424 { "a.c", MatchCase::MATCH_CASE },
426 addChild(new CaseListParserCase(m_testCtx, "end_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
429 static const char* const caseList = "a.b\na.c\r\n";
430 static const MatchCase subCases[] =
432 { "a", MatchCase::MATCH_GROUP },
433 { "b", MatchCase::NO_MATCH },
434 { "a.b", MatchCase::MATCH_CASE },
435 { "a.a", MatchCase::NO_MATCH },
436 { "a.c", MatchCase::MATCH_CASE },
438 addChild(new CaseListParserCase(m_testCtx, "end_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
441 static const char* const caseList = "a.b\nc.d\nc.e";
442 static const MatchCase subCases[] =
444 { "a", MatchCase::MATCH_GROUP },
445 { "b", MatchCase::NO_MATCH },
446 { "a.b", MatchCase::MATCH_CASE },
447 { "a.c", MatchCase::NO_MATCH },
448 { "a.d", MatchCase::NO_MATCH },
449 { "a.e", MatchCase::NO_MATCH },
450 { "c", MatchCase::MATCH_GROUP },
451 { "c.b", MatchCase::NO_MATCH },
452 { "c.d", MatchCase::MATCH_CASE },
453 { "c.e", MatchCase::MATCH_CASE },
455 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
458 static const char* const caseList = "a\nc.d\nc.e";
459 static const MatchCase subCases[] =
461 { "a", MatchCase::MATCH_CASE },
462 { "b", MatchCase::NO_MATCH },
463 { "a.b", MatchCase::NO_MATCH },
464 { "a.c", MatchCase::NO_MATCH },
465 { "a.d", MatchCase::NO_MATCH },
466 { "a.e", MatchCase::NO_MATCH },
467 { "c", MatchCase::MATCH_GROUP },
468 { "c.b", MatchCase::NO_MATCH },
469 { "c.d", MatchCase::MATCH_CASE },
470 { "c.e", MatchCase::MATCH_CASE },
472 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
475 static const char* const caseList = "c.d\nc.e\na";
476 static const MatchCase subCases[] =
478 { "a", MatchCase::MATCH_CASE },
479 { "b", MatchCase::NO_MATCH },
480 { "a.b", MatchCase::NO_MATCH },
481 { "a.c", MatchCase::NO_MATCH },
482 { "a.d", MatchCase::NO_MATCH },
483 { "a.e", MatchCase::NO_MATCH },
484 { "c", MatchCase::MATCH_GROUP },
485 { "c.b", MatchCase::NO_MATCH },
486 { "c.d", MatchCase::MATCH_CASE },
487 { "c.e", MatchCase::MATCH_CASE },
489 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
492 static const char* const caseList = "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.x";
493 static const MatchCase subCases[] =
495 { "a", MatchCase::MATCH_GROUP },
496 { "b", MatchCase::NO_MATCH },
497 { "a.b", MatchCase::MATCH_GROUP },
498 { "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.x", MatchCase::MATCH_CASE },
500 addChild(new CaseListParserCase(m_testCtx, "long_name", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
503 static const char* const caseList =
509 static const MatchCase subCases[] =
511 { "a", MatchCase::MATCH_GROUP },
512 { "a.b", MatchCase::MATCH_GROUP },
513 { "a.b.c.d.e", MatchCase::MATCH_CASE },
514 { "a.b.c.d.g", MatchCase::MATCH_CASE },
515 { "x.y", MatchCase::MATCH_GROUP },
516 { "x.y.z", MatchCase::MATCH_CASE },
517 { "a.b.c.f", MatchCase::MATCH_CASE },
518 { "a.b.c.x", MatchCase::MATCH_CASE },
520 addChild(new CaseListParserCase(m_testCtx, "partial_prefix", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
523 static const char* const caseList =
526 static const MatchCase subCases[] =
528 { "a", MatchCase::MATCH_GROUP },
529 { "a.a", MatchCase::MATCH_GROUP },
530 { "a.b.c.d", MatchCase::MATCH_CASE },
531 { "a.b.c.d", MatchCase::MATCH_CASE },
533 addChild(new CaseListParserCase(m_testCtx, "reparenting", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases)));
537 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", ""));
538 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n"));
539 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name", ".test"));
540 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name", "test."));
544 class CaseListParserTests : public tcu::TestCaseGroup
547 CaseListParserTests (tcu::TestContext& testCtx)
548 : tcu::TestCaseGroup(testCtx, "case_list_parser", "Test case list parser tests")
554 addChild(new TrieParserTests(m_testCtx));
555 addChild(new ListParserTests(m_testCtx));
559 inline deUint32 ulpDiff (float a, float b)
561 const deUint32 ab = tcu::Float32(a).bits();
562 const deUint32 bb = tcu::Float32(b).bits();
563 return de::max(ab, bb) - de::min(ab, bb);
567 inline tcu::Vector<deUint32, Size> ulpDiff (const tcu::Vector<float, Size>& a, const tcu::Vector<float, Size>& b)
569 tcu::Vector<deUint32, Size> res;
570 for (int ndx = 0; ndx < Size; ndx++)
571 res[ndx] = ulpDiff(a[ndx], b[ndx]);
575 class ConstantInterpolationTest : public tcu::TestCase
578 ConstantInterpolationTest (tcu::TestContext& testCtx)
579 : tcu::TestCase(testCtx, "const_interpolation", "Constant value interpolation")
581 const int supportedMsaaLevels[] = {1, 2, 4, 8, 16};
583 for (int msaaNdx = 0; msaaNdx < DE_LENGTH_OF_ARRAY(supportedMsaaLevels); msaaNdx++)
585 const int numSamples = supportedMsaaLevels[msaaNdx];
588 c.rtSize = tcu::IVec3(128, 128, numSamples);
589 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
590 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
591 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
592 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
593 m_cases.push_back(c);
598 c.rtSize = tcu::IVec3(128, 128, numSamples);
599 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
600 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
601 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
602 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
603 m_cases.push_back(c);
607 c.rtSize = tcu::IVec3(129, 113, numSamples);
608 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f);
609 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
610 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
611 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
612 m_cases.push_back(c);
616 c.rtSize = tcu::IVec3(107, 131, numSamples);
617 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f);
618 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f);
619 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f);
620 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f);
621 m_cases.push_back(c);
626 de::Random rnd(0x89423f);
627 for (int ndx = 0; ndx < 25; ndx++)
629 const float depth = rnd.getFloat()*2.0f - 1.0f;
632 c.rtSize.x() = rnd.getInt(16, 256);
633 c.rtSize.y() = rnd.getInt(16, 256);
634 c.rtSize.z() = rnd.choose<int>(DE_ARRAY_BEGIN(supportedMsaaLevels), DE_ARRAY_END(supportedMsaaLevels));
636 for (int vtxNdx = 0; vtxNdx < DE_LENGTH_OF_ARRAY(c.vtx); vtxNdx++)
638 c.vtx[vtxNdx].x() = rnd.getFloat()*2.0f - 1.0f;
639 c.vtx[vtxNdx].y() = rnd.getFloat()*2.0f - 1.0f;
640 c.vtx[vtxNdx].z() = depth;
641 c.vtx[vtxNdx].w() = 1.0f;
644 for (int compNdx = 0; compNdx < 4; compNdx++)
649 v = tcu::Float32(rnd.getUint32()).asFloat();
650 } while (deFloatIsInf(v) || deFloatIsNaN(v));
651 c.varying[compNdx] = v;
653 m_cases.push_back(c);
660 m_caseIter = m_cases.begin();
661 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All iterations passed");
664 IterateResult iterate (void)
667 tcu::ScopedLogSection section(m_testCtx.getLog(), "SubCase", "");
668 runCase(*m_caseIter);
670 return (++m_caseIter != m_cases.end()) ? CONTINUE : STOP;
676 tcu::IVec3 rtSize; // (width, height, samples)
681 void runCase (const SubCase& subCase)
685 const deUint32 maxColorUlpDiff = 2;
686 const deUint32 maxDepthUlpDiff = 0;
688 const int width = subCase.rtSize.x();
689 const int height = subCase.rtSize.y();
690 const int numSamples = subCase.rtSize.z();
691 const float zn = 0.0f;
692 const float zf = 1.0f;
694 TextureLevel interpolated (TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), numSamples, width, height);
695 TextureLevel depthStencil (TextureFormat(TextureFormat::DS, TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV), numSamples, width, height);
697 m_testCtx.getLog() << TestLog::Message
698 << "RT size (w, h, #samples) = " << subCase.rtSize << "\n"
699 << "vtx[0] = " << subCase.vtx[0] << "\n"
700 << "vtx[1] = " << subCase.vtx[1] << "\n"
701 << "vtx[2] = " << subCase.vtx[2] << "\n"
702 << "color = " << subCase.varying
703 << TestLog::EndMessage;
705 clear (interpolated.getAccess(), subCase.varying - Vec4(0.0f, 0.0f, 0.0f, 1.0f));
706 clearDepth (depthStencil.getAccess(), 0.0f);
707 clearStencil (depthStencil.getAccess(), 0);
710 class VtxShader : public rr::VertexShader
714 : rr::VertexShader(2, 1)
716 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
717 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
718 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
721 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
723 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
725 rr::readVertexAttrib(packets[packetNdx]->position, inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
726 packets[packetNdx]->outputs[0] = rr::readVertexAttribFloat(inputs[1], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
731 class FragShader : public rr::FragmentShader
735 : rr::FragmentShader(1, 1)
737 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
738 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
741 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
743 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
745 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++)
747 const tcu::Vec4 interp = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
748 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, interp);
754 const rr::Program program (&vtxShader, &fragShader);
756 const rr::MultisamplePixelBufferAccess colorAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(interpolated.getAccess());
757 const rr::MultisamplePixelBufferAccess dsAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess());
758 const rr::RenderTarget renderTarget (colorAccess, dsAccess, dsAccess);
759 const rr::VertexAttrib vertexAttribs[] =
761 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, 0, 0, subCase.vtx),
762 rr::VertexAttrib(subCase.varying)
764 rr::ViewportState viewport (colorAccess);
765 rr::RenderState state (viewport);
766 const rr::DrawCommand drawCmd (state, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), vertexAttribs, rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0));
767 const rr::Renderer renderer;
772 state.fragOps.depthTestEnabled = true;
773 state.fragOps.depthFunc = rr::TESTFUNC_ALWAYS;
774 state.fragOps.stencilTestEnabled = true;
775 state.fragOps.stencilStates[rr::FACETYPE_BACK].func = rr::TESTFUNC_ALWAYS;
776 state.fragOps.stencilStates[rr::FACETYPE_BACK].dpPass = rr::STENCILOP_INCR;
777 state.fragOps.stencilStates[rr::FACETYPE_FRONT] = state.fragOps.stencilStates[rr::FACETYPE_BACK];
779 renderer.draw(drawCmd);
782 // Verify interpolated values
784 TextureLevel resolvedColor (interpolated.getFormat(), width, height); // For debugging
785 TextureLevel resolvedDepthStencil (depthStencil.getFormat(), width, height); // For debugging
786 TextureLevel errorMask (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height);
787 const ConstPixelBufferAccess interpAccess = interpolated.getAccess();
788 const ConstPixelBufferAccess dsAccess = depthStencil.getAccess();
789 const PixelBufferAccess errorAccess = errorMask.getAccess();
790 int numCoveredSamples = 0;
791 int numFailedColorSamples = 0;
792 int numFailedDepthSamples = 0;
793 const bool verifyDepth = (subCase.vtx[0].z() == subCase.vtx[1].z()) &&
794 (subCase.vtx[1].z() == subCase.vtx[2].z());
795 const float refDepth = subCase.vtx[0].z()*(zf - zn)/2.0f + (zn + zf)/2.0f;
797 rr::resolveMultisampleBuffer(resolvedColor.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(interpolated.getAccess()));
798 rr::resolveMultisampleBuffer(resolvedDepthStencil.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess()));
799 clear(errorAccess, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
801 for (int y = 0; y < height; y++)
803 for (int x = 0; x < width; x++)
805 for (int sampleNdx = 0; sampleNdx < numSamples; sampleNdx++)
807 if (dsAccess.getPixStencil(sampleNdx, x, y) != 0)
809 const Vec4 color = interpAccess.getPixel(sampleNdx, x, y);
810 const UVec4 colorDiff = ulpDiff(color, subCase.varying);
811 const bool colorOk = boolAll(lessThanEqual(colorDiff, tcu::UVec4(maxColorUlpDiff)));
813 const float depth = dsAccess.getPixDepth(sampleNdx, x, y);
814 const deUint32 depthDiff = ulpDiff(depth, refDepth);
815 const bool depthOk = verifyDepth && (depthDiff <= maxDepthUlpDiff);
817 const int maxMsgs = 10;
819 numCoveredSamples += 1;
823 numFailedColorSamples += 1;
825 if (numFailedColorSamples <= maxMsgs)
826 m_testCtx.getLog() << TestLog::Message
827 << "FAIL: " << tcu::IVec3(x, y, sampleNdx)
828 << " color ulp diff = " << colorDiff
829 << TestLog::EndMessage;
833 numFailedDepthSamples += 1;
835 if (!colorOk || !depthOk)
836 errorAccess.setPixel(errorAccess.getPixel(x, y) + Vec4(1.0f, -1.0f, 0.0f, 0.0f) / float(numSamples-1), x, y);
842 m_testCtx.getLog() << TestLog::Image("ResolvedColor", "Resolved colorbuffer", resolvedColor)
843 << TestLog::Image("ResolvedDepthStencil", "Resolved depth- & stencilbuffer", resolvedDepthStencil);
845 if (numFailedColorSamples != 0 || numFailedDepthSamples != 0)
847 m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
849 if (numFailedColorSamples != 0)
850 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedColorSamples << " invalid color samples!" << TestLog::EndMessage;
852 if (numFailedDepthSamples != 0)
853 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedDepthSamples << " invalid depth samples!" << TestLog::EndMessage;
855 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
856 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid samples found");
859 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedColorSamples) << " / " << numCoveredSamples << " color samples passed" << TestLog::EndMessage;
860 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedDepthSamples) << " / " << numCoveredSamples << " depth samples passed" << TestLog::EndMessage;
864 vector<SubCase> m_cases;
865 vector<SubCase>::const_iterator m_caseIter;
868 class CommonFrameworkTests : public tcu::TestCaseGroup
871 CommonFrameworkTests (tcu::TestContext& testCtx)
872 : tcu::TestCaseGroup(testCtx, "common", "Tests for the common utility framework")
878 addChild(new SelfCheckCase(m_testCtx, "float_format","tcu::FloatFormat_selfTest()",
879 tcu::FloatFormat_selfTest));
880 addChild(new SelfCheckCase(m_testCtx, "either","tcu::Either_selfTest()",
881 tcu::Either_selfTest));
885 class ReferenceRendererTests : public tcu::TestCaseGroup
888 ReferenceRendererTests (tcu::TestContext& testCtx)
889 : tcu::TestCaseGroup(testCtx, "reference_renderer", "Reference renderer tests")
895 addChild(new ConstantInterpolationTest(m_testCtx));
901 FrameworkTests::FrameworkTests (tcu::TestContext& testCtx)
902 : tcu::TestCaseGroup(testCtx, "framework", "Miscellaneous framework tests")
906 FrameworkTests::~FrameworkTests (void)
910 void FrameworkTests::init (void)
912 addChild(new CommonFrameworkTests (m_testCtx));
913 addChild(new CaseListParserTests (m_testCtx));
914 addChild(new ReferenceRendererTests (m_testCtx));
915 addChild(createTextureFormatTests (m_testCtx));
916 addChild(createVulkanTests (m_testCtx));