1/*------------------------------------------------------------------------- 2 * drawElements Internal Test Module 3 * --------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Miscellaneous framework tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "ditFrameworkTests.hpp" 25#include "ditTextureFormatTests.hpp" 26#include "ditAstcTests.hpp" 27#include "ditVulkanTests.hpp" 28 29#include "tcuFloatFormat.hpp" 30#include "tcuEither.hpp" 31#include "tcuTestLog.hpp" 32#include "tcuCommandLine.hpp" 33 34#include "rrRenderer.hpp" 35#include "tcuTextureUtil.hpp" 36#include "tcuVectorUtil.hpp" 37#include "tcuFloat.hpp" 38 39#include "deRandom.hpp" 40#include "deArrayUtil.hpp" 41 42namespace dit 43{ 44 45namespace 46{ 47 48using std::string; 49using std::vector; 50using tcu::TestLog; 51 52struct MatchCase 53{ 54 enum Expected { NO_MATCH, MATCH_GROUP, MATCH_CASE, EXPECTED_LAST }; 55 56 const char* path; 57 Expected expected; 58}; 59 60const char* getMatchCaseExpectedDesc (MatchCase::Expected expected) 61{ 62 static const char* descs[] = 63 { 64 "no match", 65 "group to match", 66 "case to match" 67 }; 68 return de::getSizedArrayElement<MatchCase::EXPECTED_LAST>(descs, expected); 69} 70 71class CaseListParserCase : public tcu::TestCase 72{ 73public: 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) 79 { 80 } 81 82 IterateResult iterate (void) 83 { 84 TestLog& log = m_testCtx.getLog(); 85 tcu::CommandLine cmdLine; 86 int numPass = 0; 87 88 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage; 89 90 { 91 const char* argv[] = 92 { 93 "deqp", 94 "--deqp-caselist", 95 m_caseList 96 }; 97 98 if (!cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv)) 99 TCU_FAIL("Failed to parse case list"); 100 } 101 102 for (int subCaseNdx = 0; subCaseNdx < m_numSubCases; subCaseNdx++) 103 { 104 const MatchCase& curCase = m_subCases[subCaseNdx]; 105 bool matchGroup; 106 bool matchCase; 107 108 log << TestLog::Message << "Checking \"" << curCase.path << "\"" 109 << ", expecting " << getMatchCaseExpectedDesc(curCase.expected) 110 << TestLog::EndMessage; 111 112 matchGroup = cmdLine.checkTestGroupName(curCase.path); 113 matchCase = cmdLine.checkTestCaseName(curCase.path); 114 115 if ((matchGroup == (curCase.expected == MatchCase::MATCH_GROUP)) && 116 (matchCase == (curCase.expected == MatchCase::MATCH_CASE))) 117 { 118 log << TestLog::Message << " pass" << TestLog::EndMessage; 119 numPass += 1; 120 } 121 else 122 log << TestLog::Message << " FAIL!" << TestLog::EndMessage; 123 } 124 125 m_testCtx.setTestResult((numPass == m_numSubCases) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 126 (numPass == m_numSubCases) ? "All passed" : "Unexpected match result"); 127 128 return STOP; 129 } 130 131private: 132 const char* const m_caseList; 133 const MatchCase* const m_subCases; 134 const int m_numSubCases; 135}; 136 137class NegativeCaseListCase : public tcu::TestCase 138{ 139public: 140 NegativeCaseListCase (tcu::TestContext& testCtx, const char* name, const char* caseList) 141 : tcu::TestCase (testCtx, name, "") 142 , m_caseList (caseList) 143 { 144 } 145 146 IterateResult iterate (void) 147 { 148 TestLog& log = m_testCtx.getLog(); 149 tcu::CommandLine cmdLine; 150 151 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage; 152 153 { 154 const char* argv[] = 155 { 156 "deqp", 157 "--deqp-caselist", 158 m_caseList 159 }; 160 161 if (cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv)) 162 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Parsing passed, should have failed"); 163 else 164 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Parsing failed as expected"); 165 } 166 167 return STOP; 168 } 169 170private: 171 const char* const m_caseList; 172}; 173 174class TrieParserTests : public tcu::TestCaseGroup 175{ 176public: 177 TrieParserTests (tcu::TestContext& testCtx) 178 : tcu::TestCaseGroup(testCtx, "trie", "Test case trie parser tests") 179 { 180 } 181 182 void init (void) 183 { 184 { 185 static const char* const caseList = "{test}"; 186 static const MatchCase subCases[] = 187 { 188 { "test", MatchCase::MATCH_CASE }, 189 { "test.cd", MatchCase::NO_MATCH }, 190 }; 191 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 192 } 193 { 194 static const char* const caseList = "{a{b}}"; 195 static const MatchCase subCases[] = 196 { 197 { "a", MatchCase::MATCH_GROUP }, 198 { "b", MatchCase::NO_MATCH }, 199 { "a.b", MatchCase::MATCH_CASE }, 200 { "a.a", MatchCase::NO_MATCH }, 201 }; 202 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 203 } 204 { 205 static const char* const caseList = "{a{b,c}}"; 206 static const MatchCase subCases[] = 207 { 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 }, 213 }; 214 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 215 } 216 { 217 static const char* const caseList = "{a{b},c{d,e}}"; 218 static const MatchCase subCases[] = 219 { 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 }, 230 }; 231 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 232 } 233 { 234 static const char* const caseList = "{a,c{d,e}}"; 235 static const MatchCase subCases[] = 236 { 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 }, 247 }; 248 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 249 } 250 { 251 static const char* const caseList = "{c{d,e},a}"; 252 static const MatchCase subCases[] = 253 { 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 }, 264 }; 265 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 266 } 267 { 268 static const char* const caseList = "{test}\r"; 269 static const MatchCase subCases[] = 270 { 271 { "test", MatchCase::MATCH_CASE }, 272 { "test.cd", MatchCase::NO_MATCH }, 273 }; 274 addChild(new CaseListParserCase(m_testCtx, "trailing_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 275 } 276 { 277 static const char* const caseList = "{test}\n"; 278 static const MatchCase subCases[] = 279 { 280 { "test", MatchCase::MATCH_CASE }, 281 { "test.cd", MatchCase::NO_MATCH }, 282 }; 283 addChild(new CaseListParserCase(m_testCtx, "trailing_lf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 284 } 285 { 286 static const char* const caseList = "{test}\r\n"; 287 static const MatchCase subCases[] = 288 { 289 { "test", MatchCase::MATCH_CASE }, 290 { "test.cd", MatchCase::NO_MATCH }, 291 }; 292 addChild(new CaseListParserCase(m_testCtx, "trailing_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 293 } 294 295 // Negative tests 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}")); 324 } 325}; 326 327class ListParserTests : public tcu::TestCaseGroup 328{ 329public: 330 ListParserTests (tcu::TestContext& testCtx) 331 : tcu::TestCaseGroup(testCtx, "list", "Test case list parser tests") 332 { 333 } 334 335 void init (void) 336 { 337 { 338 static const char* const caseList = "test"; 339 static const MatchCase subCases[] = 340 { 341 { "test", MatchCase::MATCH_CASE }, 342 { "test.cd", MatchCase::NO_MATCH }, 343 }; 344 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 345 } 346 { 347 static const char* const caseList = "a.b"; 348 static const MatchCase subCases[] = 349 { 350 { "a", MatchCase::MATCH_GROUP }, 351 { "b", MatchCase::NO_MATCH }, 352 { "a.b", MatchCase::MATCH_CASE }, 353 { "a.a", MatchCase::NO_MATCH }, 354 }; 355 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 356 } 357 { 358 static const char* const caseList = "a.b\na.c"; 359 static const MatchCase subCases[] = 360 { 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 }, 366 }; 367 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 368 } 369 { 370 static const char* const caseList = "a.b\na.c"; 371 static const MatchCase subCases[] = 372 { 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 }, 378 }; 379 addChild(new CaseListParserCase(m_testCtx, "separator_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 380 } 381 { 382 static const char* const caseList = "a.b\ra.c"; 383 static const MatchCase subCases[] = 384 { 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 }, 390 }; 391 addChild(new CaseListParserCase(m_testCtx, "separator_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 392 } 393 { 394 static const char* const caseList = "a.b\r\na.c"; 395 static const MatchCase subCases[] = 396 { 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 }, 402 }; 403 addChild(new CaseListParserCase(m_testCtx, "separator_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 404 } 405 { 406 static const char* const caseList = "a.b\na.c\n"; 407 static const MatchCase subCases[] = 408 { 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 }, 414 }; 415 addChild(new CaseListParserCase(m_testCtx, "end_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 416 } 417 { 418 static const char* const caseList = "a.b\na.c\r"; 419 static const MatchCase subCases[] = 420 { 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 }, 426 }; 427 addChild(new CaseListParserCase(m_testCtx, "end_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 428 } 429 { 430 static const char* const caseList = "a.b\na.c\r\n"; 431 static const MatchCase subCases[] = 432 { 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 }, 438 }; 439 addChild(new CaseListParserCase(m_testCtx, "end_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 440 } 441 { 442 static const char* const caseList = "a.b\nc.d\nc.e"; 443 static const MatchCase subCases[] = 444 { 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 }, 455 }; 456 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 457 } 458 { 459 static const char* const caseList = "a\nc.d\nc.e"; 460 static const MatchCase subCases[] = 461 { 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 }, 472 }; 473 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 474 } 475 { 476 static const char* const caseList = "c.d\nc.e\na"; 477 static const MatchCase subCases[] = 478 { 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 }, 489 }; 490 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 491 } 492 { 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[] = 495 { 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 }, 500 }; 501 addChild(new CaseListParserCase(m_testCtx, "long_name", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 502 } 503 { 504 static const char* const caseList = 505 "a.b.c.d.e\n" 506 "a.b.c.f\n" 507 "x.y.z\n" 508 "a.b.c.d.g\n" 509 "a.b.c.x\n"; 510 static const MatchCase subCases[] = 511 { 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 }, 520 }; 521 addChild(new CaseListParserCase(m_testCtx, "partial_prefix", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 522 } 523 { 524 static const char* const caseList = 525 "a.a.c.d\n" 526 "a.b.c.d\n"; 527 static const MatchCase subCases[] = 528 { 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 }, 533 }; 534 addChild(new CaseListParserCase(m_testCtx, "reparenting", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 535 } 536 537 // Negative tests 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.")); 542 } 543}; 544 545class CaseListParserTests : public tcu::TestCaseGroup 546{ 547public: 548 CaseListParserTests (tcu::TestContext& testCtx) 549 : tcu::TestCaseGroup(testCtx, "case_list_parser", "Test case list parser tests") 550 { 551 } 552 553 void init (void) 554 { 555 addChild(new TrieParserTests(m_testCtx)); 556 addChild(new ListParserTests(m_testCtx)); 557 } 558}; 559 560inline deUint32 ulpDiff (float a, float b) 561{ 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); 565} 566 567template<int Size> 568inline tcu::Vector<deUint32, Size> ulpDiff (const tcu::Vector<float, Size>& a, const tcu::Vector<float, Size>& b) 569{ 570 tcu::Vector<deUint32, Size> res; 571 for (int ndx = 0; ndx < Size; ndx++) 572 res[ndx] = ulpDiff(a[ndx], b[ndx]); 573 return res; 574} 575 576class ConstantInterpolationTest : public tcu::TestCase 577{ 578public: 579 ConstantInterpolationTest (tcu::TestContext& testCtx) 580 : tcu::TestCase(testCtx, "const_interpolation", "Constant value interpolation") 581 { 582 const int supportedMsaaLevels[] = {1, 2, 4, 8, 16}; 583 584 for (int msaaNdx = 0; msaaNdx < DE_LENGTH_OF_ARRAY(supportedMsaaLevels); msaaNdx++) 585 { 586 const int numSamples = supportedMsaaLevels[msaaNdx]; 587 { 588 SubCase c; 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); 595 } 596 597 { 598 SubCase 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); 605 } 606 { 607 SubCase 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); 614 } 615 { 616 SubCase 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); 623 } 624 } 625 626 { 627 de::Random rnd(0x89423f); 628 for (int ndx = 0; ndx < 25; ndx++) 629 { 630 const float depth = rnd.getFloat()*2.0f - 1.0f; 631 SubCase c; 632 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)); 636 637 for (int vtxNdx = 0; vtxNdx < DE_LENGTH_OF_ARRAY(c.vtx); vtxNdx++) 638 { 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; 643 } 644 645 for (int compNdx = 0; compNdx < 4; compNdx++) 646 { 647 float v; 648 do 649 { 650 v = tcu::Float32(rnd.getUint32()).asFloat(); 651 } while (deFloatIsInf(v) || deFloatIsNaN(v)); 652 c.varying[compNdx] = v; 653 } 654 m_cases.push_back(c); 655 } 656 } 657 } 658 659 void init (void) 660 { 661 m_caseIter = m_cases.begin(); 662 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All iterations passed"); 663 } 664 665 IterateResult iterate (void) 666 { 667 { 668 tcu::ScopedLogSection section(m_testCtx.getLog(), "SubCase", ""); 669 runCase(*m_caseIter); 670 } 671 return (++m_caseIter != m_cases.end()) ? CONTINUE : STOP; 672 } 673 674protected: 675 struct SubCase 676 { 677 tcu::IVec3 rtSize; // (width, height, samples) 678 tcu::Vec4 vtx[3]; 679 tcu::Vec4 varying; 680 }; 681 682 void runCase (const SubCase& subCase) 683 { 684 using namespace tcu; 685 686 const deUint32 maxColorUlpDiff = 2; 687 const deUint32 maxDepthUlpDiff = 0; 688 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; 694 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); 697 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; 705 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); 709 710 { 711 class VtxShader : public rr::VertexShader 712 { 713 public: 714 VtxShader (void) 715 : rr::VertexShader(2, 1) 716 { 717 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 718 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 719 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 720 } 721 722 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 723 { 724 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 725 { 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); 728 } 729 } 730 } vtxShader; 731 732 class FragShader : public rr::FragmentShader 733 { 734 public: 735 FragShader (void) 736 : rr::FragmentShader(1, 1) 737 { 738 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 739 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 740 } 741 742 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 743 { 744 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 745 { 746 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++) 747 { 748 const tcu::Vec4 interp = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 749 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, interp); 750 } 751 } 752 } 753 } fragShader; 754 755 const rr::Program program (&vtxShader, &fragShader); 756 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[] = 761 { 762 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, 0, 0, subCase.vtx), 763 rr::VertexAttrib(subCase.varying) 764 }; 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; 769 770 viewport.zn = zn; 771 viewport.zf = zf; 772 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]; 779 780 renderer.draw(drawCmd); 781 } 782 783 // Verify interpolated values 784 { 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; 797 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)); 801 802 for (int y = 0; y < height; y++) 803 { 804 for (int x = 0; x < width; x++) 805 { 806 for (int sampleNdx = 0; sampleNdx < numSamples; sampleNdx++) 807 { 808 if (dsAccess.getPixStencil(sampleNdx, x, y) != 0) 809 { 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))); 813 814 const float depth = dsAccess.getPixDepth(sampleNdx, x, y); 815 const deUint32 depthDiff = ulpDiff(depth, refDepth); 816 const bool depthOk = verifyDepth && (depthDiff <= maxDepthUlpDiff); 817 818 const int maxMsgs = 10; 819 820 numCoveredSamples += 1; 821 822 if (!colorOk) 823 { 824 numFailedColorSamples += 1; 825 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; 831 } 832 833 if (!depthOk) 834 numFailedDepthSamples += 1; 835 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); 838 } 839 } 840 } 841 } 842 843 m_testCtx.getLog() << TestLog::Image("ResolvedColor", "Resolved colorbuffer", resolvedColor) 844 << TestLog::Image("ResolvedDepthStencil", "Resolved depth- & stencilbuffer", resolvedDepthStencil); 845 846 if (numFailedColorSamples != 0 || numFailedDepthSamples != 0) 847 { 848 m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask); 849 850 if (numFailedColorSamples != 0) 851 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedColorSamples << " invalid color samples!" << TestLog::EndMessage; 852 853 if (numFailedDepthSamples != 0) 854 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedDepthSamples << " invalid depth samples!" << TestLog::EndMessage; 855 856 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 857 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid samples found"); 858 } 859 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; 862 } 863 } 864 865 vector<SubCase> m_cases; 866 vector<SubCase>::const_iterator m_caseIter; 867}; 868 869class CommonFrameworkTests : public tcu::TestCaseGroup 870{ 871public: 872 CommonFrameworkTests (tcu::TestContext& testCtx) 873 : tcu::TestCaseGroup(testCtx, "common", "Tests for the common utility framework") 874 { 875 } 876 877 void init (void) 878 { 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)); 883 } 884}; 885 886class ReferenceRendererTests : public tcu::TestCaseGroup 887{ 888public: 889 ReferenceRendererTests (tcu::TestContext& testCtx) 890 : tcu::TestCaseGroup(testCtx, "reference_renderer", "Reference renderer tests") 891 { 892 } 893 894 void init (void) 895 { 896 addChild(new ConstantInterpolationTest(m_testCtx)); 897 } 898}; 899 900} // anonymous 901 902FrameworkTests::FrameworkTests (tcu::TestContext& testCtx) 903 : tcu::TestCaseGroup(testCtx, "framework", "Miscellaneous framework tests") 904{ 905} 906 907FrameworkTests::~FrameworkTests (void) 908{ 909} 910 911void FrameworkTests::init (void) 912{ 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)); 919} 920 921} // dit 922