ditFrameworkTests.cpp revision e2145884f87cdca749a754abfd246cdfe01ea2c1
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 "tcuFloatFormat.hpp" 27#include "tcuEither.hpp" 28#include "tcuTestLog.hpp" 29#include "tcuCommandLine.hpp" 30 31#include "rrRenderer.hpp" 32#include "tcuTextureUtil.hpp" 33#include "tcuVectorUtil.hpp" 34#include "tcuFloat.hpp" 35 36#include "deRandom.hpp" 37#include "deArrayUtil.hpp" 38 39namespace dit 40{ 41 42namespace 43{ 44 45using std::string; 46using std::vector; 47using tcu::TestLog; 48 49struct MatchCase 50{ 51 enum Expected { NO_MATCH, MATCH_GROUP, MATCH_CASE, EXPECTED_LAST }; 52 53 const char* path; 54 Expected expected; 55}; 56 57const char* getMatchCaseExpectedDesc (MatchCase::Expected expected) 58{ 59 static const char* descs[] = 60 { 61 "no match", 62 "group to match", 63 "case to match" 64 }; 65 return de::getSizedArrayElement<MatchCase::EXPECTED_LAST>(descs, expected); 66} 67 68class CaseListParserCase : public tcu::TestCase 69{ 70public: 71 CaseListParserCase (tcu::TestContext& testCtx, const char* name, const char* caseList, const MatchCase* subCases, int numSubCases) 72 : tcu::TestCase (testCtx, name, "") 73 , m_caseList (caseList) 74 , m_subCases (subCases) 75 , m_numSubCases (numSubCases) 76 { 77 } 78 79 IterateResult iterate (void) 80 { 81 TestLog& log = m_testCtx.getLog(); 82 tcu::CommandLine cmdLine; 83 int numPass = 0; 84 85 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage; 86 87 { 88 const char* argv[] = 89 { 90 "deqp", 91 "--deqp-caselist", 92 m_caseList 93 }; 94 95 if (!cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv)) 96 TCU_FAIL("Failed to parse case list"); 97 } 98 99 for (int subCaseNdx = 0; subCaseNdx < m_numSubCases; subCaseNdx++) 100 { 101 const MatchCase& curCase = m_subCases[subCaseNdx]; 102 bool matchGroup; 103 bool matchCase; 104 105 log << TestLog::Message << "Checking \"" << curCase.path << "\"" 106 << ", expecting " << getMatchCaseExpectedDesc(curCase.expected) 107 << TestLog::EndMessage; 108 109 matchGroup = cmdLine.checkTestGroupName(curCase.path); 110 matchCase = cmdLine.checkTestCaseName(curCase.path); 111 112 if ((matchGroup == (curCase.expected == MatchCase::MATCH_GROUP)) && 113 (matchCase == (curCase.expected == MatchCase::MATCH_CASE))) 114 { 115 log << TestLog::Message << " pass" << TestLog::EndMessage; 116 numPass += 1; 117 } 118 else 119 log << TestLog::Message << " FAIL!" << TestLog::EndMessage; 120 } 121 122 m_testCtx.setTestResult((numPass == m_numSubCases) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 123 (numPass == m_numSubCases) ? "All passed" : "Unexpected match result"); 124 125 return STOP; 126 } 127 128private: 129 const char* const m_caseList; 130 const MatchCase* const m_subCases; 131 const int m_numSubCases; 132}; 133 134class NegativeCaseListCase : public tcu::TestCase 135{ 136public: 137 NegativeCaseListCase (tcu::TestContext& testCtx, const char* name, const char* caseList) 138 : tcu::TestCase (testCtx, name, "") 139 , m_caseList (caseList) 140 { 141 } 142 143 IterateResult iterate (void) 144 { 145 TestLog& log = m_testCtx.getLog(); 146 tcu::CommandLine cmdLine; 147 148 log << TestLog::Message << "Input:\n\"" << m_caseList << "\"" << TestLog::EndMessage; 149 150 { 151 const char* argv[] = 152 { 153 "deqp", 154 "--deqp-caselist", 155 m_caseList 156 }; 157 158 if (cmdLine.parse(DE_LENGTH_OF_ARRAY(argv), argv)) 159 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Parsing passed, should have failed"); 160 else 161 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Parsing failed as expected"); 162 } 163 164 return STOP; 165 } 166 167private: 168 const char* const m_caseList; 169}; 170 171class TrieParserTests : public tcu::TestCaseGroup 172{ 173public: 174 TrieParserTests (tcu::TestContext& testCtx) 175 : tcu::TestCaseGroup(testCtx, "trie", "Test case trie parser tests") 176 { 177 } 178 179 void init (void) 180 { 181 { 182 static const char* const caseList = "{test}"; 183 static const MatchCase subCases[] = 184 { 185 { "test", MatchCase::MATCH_CASE }, 186 { "test.cd", MatchCase::NO_MATCH }, 187 }; 188 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 189 } 190 { 191 static const char* const caseList = "{a{b}}"; 192 static const MatchCase subCases[] = 193 { 194 { "a", MatchCase::MATCH_GROUP }, 195 { "b", MatchCase::NO_MATCH }, 196 { "a.b", MatchCase::MATCH_CASE }, 197 { "a.a", MatchCase::NO_MATCH }, 198 }; 199 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 200 } 201 { 202 static const char* const caseList = "{a{b,c}}"; 203 static const MatchCase subCases[] = 204 { 205 { "a", MatchCase::MATCH_GROUP }, 206 { "b", MatchCase::NO_MATCH }, 207 { "a.b", MatchCase::MATCH_CASE }, 208 { "a.a", MatchCase::NO_MATCH }, 209 { "a.c", MatchCase::MATCH_CASE }, 210 }; 211 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 212 } 213 { 214 static const char* const caseList = "{a{b},c{d,e}}"; 215 static const MatchCase subCases[] = 216 { 217 { "a", MatchCase::MATCH_GROUP }, 218 { "b", MatchCase::NO_MATCH }, 219 { "a.b", MatchCase::MATCH_CASE }, 220 { "a.c", MatchCase::NO_MATCH }, 221 { "a.d", MatchCase::NO_MATCH }, 222 { "a.e", MatchCase::NO_MATCH }, 223 { "c", MatchCase::MATCH_GROUP }, 224 { "c.b", MatchCase::NO_MATCH }, 225 { "c.d", MatchCase::MATCH_CASE }, 226 { "c.e", MatchCase::MATCH_CASE }, 227 }; 228 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 229 } 230 { 231 static const char* const caseList = "{a,c{d,e}}"; 232 static const MatchCase subCases[] = 233 { 234 { "a", MatchCase::MATCH_CASE }, 235 { "b", MatchCase::NO_MATCH }, 236 { "a.b", MatchCase::NO_MATCH }, 237 { "a.c", MatchCase::NO_MATCH }, 238 { "a.d", MatchCase::NO_MATCH }, 239 { "a.e", MatchCase::NO_MATCH }, 240 { "c", MatchCase::MATCH_GROUP }, 241 { "c.b", MatchCase::NO_MATCH }, 242 { "c.d", MatchCase::MATCH_CASE }, 243 { "c.e", MatchCase::MATCH_CASE }, 244 }; 245 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 246 } 247 { 248 static const char* const caseList = "{c{d,e},a}"; 249 static const MatchCase subCases[] = 250 { 251 { "a", MatchCase::MATCH_CASE }, 252 { "b", MatchCase::NO_MATCH }, 253 { "a.b", MatchCase::NO_MATCH }, 254 { "a.c", MatchCase::NO_MATCH }, 255 { "a.d", MatchCase::NO_MATCH }, 256 { "a.e", MatchCase::NO_MATCH }, 257 { "c", MatchCase::MATCH_GROUP }, 258 { "c.b", MatchCase::NO_MATCH }, 259 { "c.d", MatchCase::MATCH_CASE }, 260 { "c.e", MatchCase::MATCH_CASE }, 261 }; 262 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 263 } 264 { 265 static const char* const caseList = "{test}\r"; 266 static const MatchCase subCases[] = 267 { 268 { "test", MatchCase::MATCH_CASE }, 269 { "test.cd", MatchCase::NO_MATCH }, 270 }; 271 addChild(new CaseListParserCase(m_testCtx, "trailing_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 272 } 273 { 274 static const char* const caseList = "{test}\n"; 275 static const MatchCase subCases[] = 276 { 277 { "test", MatchCase::MATCH_CASE }, 278 { "test.cd", MatchCase::NO_MATCH }, 279 }; 280 addChild(new CaseListParserCase(m_testCtx, "trailing_lf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 281 } 282 { 283 static const char* const caseList = "{test}\r\n"; 284 static const MatchCase subCases[] = 285 { 286 { "test", MatchCase::MATCH_CASE }, 287 { "test.cd", MatchCase::NO_MATCH }, 288 }; 289 addChild(new CaseListParserCase(m_testCtx, "trailing_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 290 } 291 292 // Negative tests 293 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", "")); 294 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n")); 295 addChild(new NegativeCaseListCase(m_testCtx, "empty_root", "{}")); 296 addChild(new NegativeCaseListCase(m_testCtx, "empty_group", "{test{}}")); 297 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_1", "{{}}")); 298 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name_2", "{{test}}")); 299 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_1", "{")); 300 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_2", "{test")); 301 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_3", "{test,")); 302 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_4", "{test{a}")); 303 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_root_5", "{a,b")); 304 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_1", "{test{")); 305 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_2", "{test{a")); 306 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_3", "{test{a,")); 307 addChild(new NegativeCaseListCase(m_testCtx, "unterminated_group_4", "{test{a,b")); 308 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_1", "{a,,b}")); 309 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_2", "{,b}")); 310 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name_3", "{a,}")); 311 addChild(new NegativeCaseListCase(m_testCtx, "no_separator", "{a{b}c}")); 312 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_1", "{a.b}")); 313 addChild(new NegativeCaseListCase(m_testCtx, "invalid_char_2", "{a[]}")); 314 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_1", "{a}}")); 315 addChild(new NegativeCaseListCase(m_testCtx, "trailing_char_2", "{a}x")); 316 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_1", "{\na}")); 317 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_2", "{a\n,b}")); 318 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_3", "{a,\nb}")); 319 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_4", "{a{b\n}}")); 320 addChild(new NegativeCaseListCase(m_testCtx, "embedded_newline_5", "{a{b}\n}")); 321 } 322}; 323 324class ListParserTests : public tcu::TestCaseGroup 325{ 326public: 327 ListParserTests (tcu::TestContext& testCtx) 328 : tcu::TestCaseGroup(testCtx, "list", "Test case list parser tests") 329 { 330 } 331 332 void init (void) 333 { 334 { 335 static const char* const caseList = "test"; 336 static const MatchCase subCases[] = 337 { 338 { "test", MatchCase::MATCH_CASE }, 339 { "test.cd", MatchCase::NO_MATCH }, 340 }; 341 addChild(new CaseListParserCase(m_testCtx, "single_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 342 } 343 { 344 static const char* const caseList = "a.b"; 345 static const MatchCase subCases[] = 346 { 347 { "a", MatchCase::MATCH_GROUP }, 348 { "b", MatchCase::NO_MATCH }, 349 { "a.b", MatchCase::MATCH_CASE }, 350 { "a.a", MatchCase::NO_MATCH }, 351 }; 352 addChild(new CaseListParserCase(m_testCtx, "simple_group_1", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 353 } 354 { 355 static const char* const caseList = "a.b\na.c"; 356 static const MatchCase subCases[] = 357 { 358 { "a", MatchCase::MATCH_GROUP }, 359 { "b", MatchCase::NO_MATCH }, 360 { "a.b", MatchCase::MATCH_CASE }, 361 { "a.a", MatchCase::NO_MATCH }, 362 { "a.c", MatchCase::MATCH_CASE }, 363 }; 364 addChild(new CaseListParserCase(m_testCtx, "simple_group_2", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 365 } 366 { 367 static const char* const caseList = "a.b\na.c"; 368 static const MatchCase subCases[] = 369 { 370 { "a", MatchCase::MATCH_GROUP }, 371 { "b", MatchCase::NO_MATCH }, 372 { "a.b", MatchCase::MATCH_CASE }, 373 { "a.a", MatchCase::NO_MATCH }, 374 { "a.c", MatchCase::MATCH_CASE }, 375 }; 376 addChild(new CaseListParserCase(m_testCtx, "separator_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 377 } 378 { 379 static const char* const caseList = "a.b\ra.c"; 380 static const MatchCase subCases[] = 381 { 382 { "a", MatchCase::MATCH_GROUP }, 383 { "b", MatchCase::NO_MATCH }, 384 { "a.b", MatchCase::MATCH_CASE }, 385 { "a.a", MatchCase::NO_MATCH }, 386 { "a.c", MatchCase::MATCH_CASE }, 387 }; 388 addChild(new CaseListParserCase(m_testCtx, "separator_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 389 } 390 { 391 static const char* const caseList = "a.b\r\na.c"; 392 static const MatchCase subCases[] = 393 { 394 { "a", MatchCase::MATCH_GROUP }, 395 { "b", MatchCase::NO_MATCH }, 396 { "a.b", MatchCase::MATCH_CASE }, 397 { "a.a", MatchCase::NO_MATCH }, 398 { "a.c", MatchCase::MATCH_CASE }, 399 }; 400 addChild(new CaseListParserCase(m_testCtx, "separator_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 401 } 402 { 403 static const char* const caseList = "a.b\na.c\n"; 404 static const MatchCase subCases[] = 405 { 406 { "a", MatchCase::MATCH_GROUP }, 407 { "b", MatchCase::NO_MATCH }, 408 { "a.b", MatchCase::MATCH_CASE }, 409 { "a.a", MatchCase::NO_MATCH }, 410 { "a.c", MatchCase::MATCH_CASE }, 411 }; 412 addChild(new CaseListParserCase(m_testCtx, "end_ln", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 413 } 414 { 415 static const char* const caseList = "a.b\na.c\r"; 416 static const MatchCase subCases[] = 417 { 418 { "a", MatchCase::MATCH_GROUP }, 419 { "b", MatchCase::NO_MATCH }, 420 { "a.b", MatchCase::MATCH_CASE }, 421 { "a.a", MatchCase::NO_MATCH }, 422 { "a.c", MatchCase::MATCH_CASE }, 423 }; 424 addChild(new CaseListParserCase(m_testCtx, "end_cr", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 425 } 426 { 427 static const char* const caseList = "a.b\na.c\r\n"; 428 static const MatchCase subCases[] = 429 { 430 { "a", MatchCase::MATCH_GROUP }, 431 { "b", MatchCase::NO_MATCH }, 432 { "a.b", MatchCase::MATCH_CASE }, 433 { "a.a", MatchCase::NO_MATCH }, 434 { "a.c", MatchCase::MATCH_CASE }, 435 }; 436 addChild(new CaseListParserCase(m_testCtx, "end_crlf", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 437 } 438 { 439 static const char* const caseList = "a.b\nc.d\nc.e"; 440 static const MatchCase subCases[] = 441 { 442 { "a", MatchCase::MATCH_GROUP }, 443 { "b", MatchCase::NO_MATCH }, 444 { "a.b", MatchCase::MATCH_CASE }, 445 { "a.c", MatchCase::NO_MATCH }, 446 { "a.d", MatchCase::NO_MATCH }, 447 { "a.e", MatchCase::NO_MATCH }, 448 { "c", MatchCase::MATCH_GROUP }, 449 { "c.b", MatchCase::NO_MATCH }, 450 { "c.d", MatchCase::MATCH_CASE }, 451 { "c.e", MatchCase::MATCH_CASE }, 452 }; 453 addChild(new CaseListParserCase(m_testCtx, "two_groups", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 454 } 455 { 456 static const char* const caseList = "a\nc.d\nc.e"; 457 static const MatchCase subCases[] = 458 { 459 { "a", MatchCase::MATCH_CASE }, 460 { "b", MatchCase::NO_MATCH }, 461 { "a.b", MatchCase::NO_MATCH }, 462 { "a.c", MatchCase::NO_MATCH }, 463 { "a.d", MatchCase::NO_MATCH }, 464 { "a.e", MatchCase::NO_MATCH }, 465 { "c", MatchCase::MATCH_GROUP }, 466 { "c.b", MatchCase::NO_MATCH }, 467 { "c.d", MatchCase::MATCH_CASE }, 468 { "c.e", MatchCase::MATCH_CASE }, 469 }; 470 addChild(new CaseListParserCase(m_testCtx, "case_group", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 471 } 472 { 473 static const char* const caseList = "c.d\nc.e\na"; 474 static const MatchCase subCases[] = 475 { 476 { "a", MatchCase::MATCH_CASE }, 477 { "b", MatchCase::NO_MATCH }, 478 { "a.b", MatchCase::NO_MATCH }, 479 { "a.c", MatchCase::NO_MATCH }, 480 { "a.d", MatchCase::NO_MATCH }, 481 { "a.e", MatchCase::NO_MATCH }, 482 { "c", MatchCase::MATCH_GROUP }, 483 { "c.b", MatchCase::NO_MATCH }, 484 { "c.d", MatchCase::MATCH_CASE }, 485 { "c.e", MatchCase::MATCH_CASE }, 486 }; 487 addChild(new CaseListParserCase(m_testCtx, "group_case", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 488 } 489 { 490 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"; 491 static const MatchCase subCases[] = 492 { 493 { "a", MatchCase::MATCH_GROUP }, 494 { "b", MatchCase::NO_MATCH }, 495 { "a.b", MatchCase::MATCH_GROUP }, 496 { "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.x", MatchCase::MATCH_CASE }, 497 }; 498 addChild(new CaseListParserCase(m_testCtx, "long_name", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 499 } 500 { 501 static const char* const caseList = 502 "a.b.c.d.e\n" 503 "a.b.c.f\n" 504 "x.y.z\n" 505 "a.b.c.d.g\n" 506 "a.b.c.x\n"; 507 static const MatchCase subCases[] = 508 { 509 { "a", MatchCase::MATCH_GROUP }, 510 { "a.b", MatchCase::MATCH_GROUP }, 511 { "a.b.c.d.e", MatchCase::MATCH_CASE }, 512 { "a.b.c.d.g", MatchCase::MATCH_CASE }, 513 { "x.y", MatchCase::MATCH_GROUP }, 514 { "x.y.z", MatchCase::MATCH_CASE }, 515 { "a.b.c.f", MatchCase::MATCH_CASE }, 516 { "a.b.c.x", MatchCase::MATCH_CASE }, 517 }; 518 addChild(new CaseListParserCase(m_testCtx, "partial_prefix", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 519 } 520 { 521 static const char* const caseList = 522 "a.a.c.d\n" 523 "a.b.c.d\n"; 524 static const MatchCase subCases[] = 525 { 526 { "a", MatchCase::MATCH_GROUP }, 527 { "a.a", MatchCase::MATCH_GROUP }, 528 { "a.b.c.d", MatchCase::MATCH_CASE }, 529 { "a.b.c.d", MatchCase::MATCH_CASE }, 530 }; 531 addChild(new CaseListParserCase(m_testCtx, "reparenting", caseList, subCases, DE_LENGTH_OF_ARRAY(subCases))); 532 } 533 534 // Negative tests 535 addChild(new NegativeCaseListCase(m_testCtx, "empty_string", "")); 536 addChild(new NegativeCaseListCase(m_testCtx, "empty_line", "\n")); 537 addChild(new NegativeCaseListCase(m_testCtx, "empty_group_name", ".test")); 538 addChild(new NegativeCaseListCase(m_testCtx, "empty_case_name", "test.")); 539 } 540}; 541 542class CaseListParserTests : public tcu::TestCaseGroup 543{ 544public: 545 CaseListParserTests (tcu::TestContext& testCtx) 546 : tcu::TestCaseGroup(testCtx, "case_list_parser", "Test case list parser tests") 547 { 548 } 549 550 void init (void) 551 { 552 addChild(new TrieParserTests(m_testCtx)); 553 addChild(new ListParserTests(m_testCtx)); 554 } 555}; 556 557inline deUint32 ulpDiff (float a, float b) 558{ 559 const deUint32 ab = tcu::Float32(a).bits(); 560 const deUint32 bb = tcu::Float32(b).bits(); 561 return de::max(ab, bb) - de::min(ab, bb); 562} 563 564template<int Size> 565inline tcu::Vector<deUint32, Size> ulpDiff (const tcu::Vector<float, Size>& a, const tcu::Vector<float, Size>& b) 566{ 567 tcu::Vector<deUint32, Size> res; 568 for (int ndx = 0; ndx < Size; ndx++) 569 res[ndx] = ulpDiff(a[ndx], b[ndx]); 570 return res; 571} 572 573class ConstantInterpolationTest : public tcu::TestCase 574{ 575public: 576 ConstantInterpolationTest (tcu::TestContext& testCtx) 577 : tcu::TestCase(testCtx, "const_interpolation", "Constant value interpolation") 578 { 579 const int supportedMsaaLevels[] = {1, 2, 4, 8, 16}; 580 581 for (int msaaNdx = 0; msaaNdx < DE_LENGTH_OF_ARRAY(supportedMsaaLevels); msaaNdx++) 582 { 583 const int numSamples = supportedMsaaLevels[msaaNdx]; 584 { 585 SubCase c; 586 c.rtSize = tcu::IVec3(128, 128, numSamples); 587 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f); 588 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f); 589 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f); 590 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f); 591 m_cases.push_back(c); 592 } 593 594 { 595 SubCase c; 596 c.rtSize = tcu::IVec3(128, 128, numSamples); 597 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f); 598 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f); 599 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f); 600 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f); 601 m_cases.push_back(c); 602 } 603 { 604 SubCase c; 605 c.rtSize = tcu::IVec3(129, 113, numSamples); 606 c.vtx[0] = tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f); 607 c.vtx[1] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f); 608 c.vtx[2] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f); 609 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f); 610 m_cases.push_back(c); 611 } 612 { 613 SubCase c; 614 c.rtSize = tcu::IVec3(107, 131, numSamples); 615 c.vtx[0] = tcu::Vec4(-1.0f, +1.0f, 0.5f, 1.0f); 616 c.vtx[1] = tcu::Vec4(+1.0f, -1.0f, 0.5f, 1.0f); 617 c.vtx[2] = tcu::Vec4(+1.0f, +1.0f, 0.5f, 1.0f); 618 c.varying = tcu::Vec4(0.0f, 1.0f, 8.0f, -8.0f); 619 m_cases.push_back(c); 620 } 621 } 622 623 { 624 de::Random rnd(0x89423f); 625 for (int ndx = 0; ndx < 25; ndx++) 626 { 627 const float depth = rnd.getFloat()*2.0f - 1.0f; 628 SubCase c; 629 630 c.rtSize.x() = rnd.getInt(16, 256); 631 c.rtSize.y() = rnd.getInt(16, 256); 632 c.rtSize.z() = rnd.choose<int>(DE_ARRAY_BEGIN(supportedMsaaLevels), DE_ARRAY_END(supportedMsaaLevels)); 633 634 for (int vtxNdx = 0; vtxNdx < DE_LENGTH_OF_ARRAY(c.vtx); vtxNdx++) 635 { 636 c.vtx[vtxNdx].x() = rnd.getFloat()*2.0f - 1.0f; 637 c.vtx[vtxNdx].y() = rnd.getFloat()*2.0f - 1.0f; 638 c.vtx[vtxNdx].z() = depth; 639 c.vtx[vtxNdx].w() = 1.0f; 640 } 641 642 for (int compNdx = 0; compNdx < 4; compNdx++) 643 { 644 float v; 645 do 646 { 647 v = tcu::Float32(rnd.getUint32()).asFloat(); 648 } while (deFloatIsInf(v) || deFloatIsNaN(v)); 649 c.varying[compNdx] = v; 650 } 651 m_cases.push_back(c); 652 } 653 } 654 } 655 656 void init (void) 657 { 658 m_caseIter = m_cases.begin(); 659 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All iterations passed"); 660 } 661 662 IterateResult iterate (void) 663 { 664 { 665 tcu::ScopedLogSection section(m_testCtx.getLog(), "SubCase", ""); 666 runCase(*m_caseIter); 667 } 668 return (++m_caseIter != m_cases.end()) ? CONTINUE : STOP; 669 } 670 671protected: 672 struct SubCase 673 { 674 tcu::IVec3 rtSize; // (width, height, samples) 675 tcu::Vec4 vtx[3]; 676 tcu::Vec4 varying; 677 }; 678 679 void runCase (const SubCase& subCase) 680 { 681 using namespace tcu; 682 683 const deUint32 maxColorUlpDiff = 2; 684 const deUint32 maxDepthUlpDiff = 0; 685 686 const int width = subCase.rtSize.x(); 687 const int height = subCase.rtSize.y(); 688 const int numSamples = subCase.rtSize.z(); 689 const float zn = 0.0f; 690 const float zf = 1.0f; 691 692 TextureLevel interpolated (TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), numSamples, width, height); 693 TextureLevel depthStencil (TextureFormat(TextureFormat::DS, TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV), numSamples, width, height); 694 695 m_testCtx.getLog() << TestLog::Message 696 << "RT size (w, h, #samples) = " << subCase.rtSize << "\n" 697 << "vtx[0] = " << subCase.vtx[0] << "\n" 698 << "vtx[1] = " << subCase.vtx[1] << "\n" 699 << "vtx[2] = " << subCase.vtx[2] << "\n" 700 << "color = " << subCase.varying 701 << TestLog::EndMessage; 702 703 clear (interpolated.getAccess(), subCase.varying - Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 704 clearDepth (depthStencil.getAccess(), 0.0f); 705 clearStencil (depthStencil.getAccess(), 0); 706 707 { 708 class VtxShader : public rr::VertexShader 709 { 710 public: 711 VtxShader (void) 712 : rr::VertexShader(2, 1) 713 { 714 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 715 m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; 716 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 717 } 718 719 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 720 { 721 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 722 { 723 rr::readVertexAttrib(packets[packetNdx]->position, inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx); 724 packets[packetNdx]->outputs[0] = rr::readVertexAttribFloat(inputs[1], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx); 725 } 726 } 727 } vtxShader; 728 729 class FragShader : public rr::FragmentShader 730 { 731 public: 732 FragShader (void) 733 : rr::FragmentShader(1, 1) 734 { 735 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; 736 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; 737 } 738 739 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 740 { 741 for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 742 { 743 for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++) 744 { 745 const tcu::Vec4 interp = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx); 746 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, interp); 747 } 748 } 749 } 750 } fragShader; 751 752 const rr::Program program (&vtxShader, &fragShader); 753 754 const rr::MultisamplePixelBufferAccess colorAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(interpolated.getAccess()); 755 const rr::MultisamplePixelBufferAccess dsAccess = rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess()); 756 const rr::RenderTarget renderTarget (colorAccess, dsAccess, dsAccess); 757 const rr::VertexAttrib vertexAttribs[] = 758 { 759 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, 0, 0, subCase.vtx), 760 rr::VertexAttrib(subCase.varying) 761 }; 762 rr::ViewportState viewport (colorAccess); 763 rr::RenderState state (viewport); 764 const rr::DrawCommand drawCmd (state, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), vertexAttribs, rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0)); 765 const rr::Renderer renderer; 766 767 viewport.zn = zn; 768 viewport.zf = zf; 769 770 state.fragOps.depthTestEnabled = true; 771 state.fragOps.depthFunc = rr::TESTFUNC_ALWAYS; 772 state.fragOps.stencilTestEnabled = true; 773 state.fragOps.stencilStates[rr::FACETYPE_BACK].func = rr::TESTFUNC_ALWAYS; 774 state.fragOps.stencilStates[rr::FACETYPE_BACK].dpPass = rr::STENCILOP_INCR; 775 state.fragOps.stencilStates[rr::FACETYPE_FRONT] = state.fragOps.stencilStates[rr::FACETYPE_BACK]; 776 777 renderer.draw(drawCmd); 778 } 779 780 // Verify interpolated values 781 { 782 TextureLevel resolvedColor (interpolated.getFormat(), width, height); // For debugging 783 TextureLevel resolvedDepthStencil (depthStencil.getFormat(), width, height); // For debugging 784 TextureLevel errorMask (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height); 785 const ConstPixelBufferAccess interpAccess = interpolated.getAccess(); 786 const ConstPixelBufferAccess dsAccess = depthStencil.getAccess(); 787 const PixelBufferAccess errorAccess = errorMask.getAccess(); 788 int numCoveredSamples = 0; 789 int numFailedColorSamples = 0; 790 int numFailedDepthSamples = 0; 791 const bool verifyDepth = (subCase.vtx[0].z() == subCase.vtx[1].z()) && 792 (subCase.vtx[1].z() == subCase.vtx[2].z()); 793 const float refDepth = subCase.vtx[0].z()*(zf - zn)/2.0f + (zn + zf)/2.0f; 794 795 rr::resolveMultisampleBuffer(resolvedColor.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(interpolated.getAccess())); 796 rr::resolveMultisampleBuffer(resolvedDepthStencil.getAccess(), rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(depthStencil.getAccess())); 797 clear(errorAccess, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 798 799 for (int y = 0; y < height; y++) 800 { 801 for (int x = 0; x < width; x++) 802 { 803 for (int sampleNdx = 0; sampleNdx < numSamples; sampleNdx++) 804 { 805 if (dsAccess.getPixStencil(sampleNdx, x, y) != 0) 806 { 807 const Vec4 color = interpAccess.getPixel(sampleNdx, x, y); 808 const UVec4 colorDiff = ulpDiff(color, subCase.varying); 809 const bool colorOk = boolAll(lessThanEqual(colorDiff, tcu::UVec4(maxColorUlpDiff))); 810 811 const float depth = dsAccess.getPixDepth(sampleNdx, x, y); 812 const deUint32 depthDiff = ulpDiff(depth, refDepth); 813 const bool depthOk = verifyDepth && (depthDiff <= maxDepthUlpDiff); 814 815 const int maxMsgs = 10; 816 817 numCoveredSamples += 1; 818 819 if (!colorOk) 820 { 821 numFailedColorSamples += 1; 822 823 if (numFailedColorSamples <= maxMsgs) 824 m_testCtx.getLog() << TestLog::Message 825 << "FAIL: " << tcu::IVec3(x, y, sampleNdx) 826 << " color ulp diff = " << colorDiff 827 << TestLog::EndMessage; 828 } 829 830 if (!depthOk) 831 numFailedDepthSamples += 1; 832 833 if (!colorOk || !depthOk) 834 errorAccess.setPixel(errorAccess.getPixel(x, y) + Vec4(1.0f, -1.0f, 0.0f, 0.0f) / float(numSamples-1), x, y); 835 } 836 } 837 } 838 } 839 840 m_testCtx.getLog() << TestLog::Image("ResolvedColor", "Resolved colorbuffer", resolvedColor) 841 << TestLog::Image("ResolvedDepthStencil", "Resolved depth- & stencilbuffer", resolvedDepthStencil); 842 843 if (numFailedColorSamples != 0 || numFailedDepthSamples != 0) 844 { 845 m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask); 846 847 if (numFailedColorSamples != 0) 848 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedColorSamples << " invalid color samples!" << TestLog::EndMessage; 849 850 if (numFailedDepthSamples != 0) 851 m_testCtx.getLog() << TestLog::Message << "FAIL: Found " << numFailedDepthSamples << " invalid depth samples!" << TestLog::EndMessage; 852 853 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 854 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid samples found"); 855 } 856 857 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedColorSamples) << " / " << numCoveredSamples << " color samples passed" << TestLog::EndMessage; 858 m_testCtx.getLog() << TestLog::Message << (numCoveredSamples-numFailedDepthSamples) << " / " << numCoveredSamples << " depth samples passed" << TestLog::EndMessage; 859 } 860 } 861 862 vector<SubCase> m_cases; 863 vector<SubCase>::const_iterator m_caseIter; 864}; 865 866class CommonFrameworkTests : public tcu::TestCaseGroup 867{ 868public: 869 CommonFrameworkTests (tcu::TestContext& testCtx) 870 : tcu::TestCaseGroup(testCtx, "common", "Tests for the common utility framework") 871 { 872 } 873 874 void init (void) 875 { 876 addChild(new SelfCheckCase(m_testCtx, "float_format","tcu::FloatFormat_selfTest()", 877 tcu::FloatFormat_selfTest)); 878 addChild(new SelfCheckCase(m_testCtx, "either","tcu::Either_selfTest()", 879 tcu::Either_selfTest)); 880 } 881}; 882 883class ReferenceRendererTests : public tcu::TestCaseGroup 884{ 885public: 886 ReferenceRendererTests (tcu::TestContext& testCtx) 887 : tcu::TestCaseGroup(testCtx, "reference_renderer", "Reference renderer tests") 888 { 889 } 890 891 void init (void) 892 { 893 addChild(new ConstantInterpolationTest(m_testCtx)); 894 } 895}; 896 897} // anonymous 898 899FrameworkTests::FrameworkTests (tcu::TestContext& testCtx) 900 : tcu::TestCaseGroup(testCtx, "framework", "Miscellaneous framework tests") 901{ 902} 903 904FrameworkTests::~FrameworkTests (void) 905{ 906} 907 908void FrameworkTests::init (void) 909{ 910 addChild(new CommonFrameworkTests (m_testCtx)); 911 addChild(new CaseListParserTests (m_testCtx)); 912 addChild(new ReferenceRendererTests (m_testCtx)); 913 addChild(createTextureFormatTests (m_testCtx)); 914} 915 916} // dit 917