1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 2.0 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 Drawing tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es2fDrawTests.hpp" 25 #include "glsDrawTest.hpp" 26 #include "tcuRenderTarget.hpp" 27 #include "deRandom.hpp" 28 #include "deStringUtil.hpp" 29 #include "deUniquePtr.hpp" 30 #include "deSTLUtil.hpp" 31 32 #include "glwEnums.hpp" 33 34 #include <set> 35 36 namespace deqp 37 { 38 namespace gles2 39 { 40 namespace Functional 41 { 42 namespace 43 { 44 45 enum TestIterationType 46 { 47 TYPE_DRAW_COUNT, // !< test with 1, 5, and 25 primitives 48 49 TYPE_LAST 50 }; 51 52 static void addTestIterations (gls::DrawTest* test, const gls::DrawTestSpec& baseSpec, TestIterationType type) 53 { 54 gls::DrawTestSpec spec(baseSpec); 55 56 if (type == TYPE_DRAW_COUNT) 57 { 58 spec.primitiveCount = 1; 59 test->addIteration(spec, "draw count = 1"); 60 61 spec.primitiveCount = 5; 62 test->addIteration(spec, "draw count = 5"); 63 64 spec.primitiveCount = 25; 65 test->addIteration(spec, "draw count = 25"); 66 } 67 else 68 DE_ASSERT(false); 69 } 70 71 static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method) 72 { 73 spec.apiType = glu::ApiType::es(2,0); 74 spec.primitive = gls::DrawTestSpec::PRIMITIVE_TRIANGLES; 75 spec.primitiveCount = 5; 76 spec.drawMethod = method; 77 spec.indexType = gls::DrawTestSpec::INDEXTYPE_LAST; 78 spec.indexPointerOffset = 0; 79 spec.indexStorage = gls::DrawTestSpec::STORAGE_LAST; 80 spec.first = 0; 81 spec.indexMin = 0; 82 spec.indexMax = 0; 83 spec.instanceCount = 1; 84 85 spec.attribs.resize(2); 86 87 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 88 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 89 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 90 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 91 spec.attribs[0].componentCount = 4; 92 spec.attribs[0].offset = 0; 93 spec.attribs[0].stride = 0; 94 spec.attribs[0].normalize = false; 95 spec.attribs[0].instanceDivisor = 0; 96 spec.attribs[0].useDefaultAttribute = false; 97 98 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 99 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 100 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER; 101 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 102 spec.attribs[1].componentCount = 2; 103 spec.attribs[1].offset = 0; 104 spec.attribs[1].stride = 0; 105 spec.attribs[1].normalize = false; 106 spec.attribs[1].instanceDivisor = 0; 107 spec.attribs[1].useDefaultAttribute = false; 108 } 109 110 111 class AttributeGroup : public TestCaseGroup 112 { 113 public: 114 AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage); 115 ~AttributeGroup (void); 116 117 void init (void); 118 119 private: 120 gls::DrawTestSpec::DrawMethod m_method; 121 gls::DrawTestSpec::Primitive m_primitive; 122 gls::DrawTestSpec::IndexType m_indexType; 123 gls::DrawTestSpec::Storage m_indexStorage; 124 }; 125 126 AttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage) 127 : TestCaseGroup (context, name, descr) 128 , m_method (drawMethod) 129 , m_primitive (primitive) 130 , m_indexType (indexType) 131 , m_indexStorage (indexStorage) 132 { 133 } 134 135 AttributeGroup::~AttributeGroup (void) 136 { 137 } 138 139 void AttributeGroup::init (void) 140 { 141 // Single attribute 142 { 143 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array."); 144 gls::DrawTestSpec spec; 145 146 spec.apiType = glu::ApiType::es(2,0); 147 spec.primitive = m_primitive; 148 spec.primitiveCount = 0; 149 spec.drawMethod = m_method; 150 spec.indexType = m_indexType; 151 spec.indexPointerOffset = 0; 152 spec.indexStorage = m_indexStorage; 153 spec.first = 0; 154 spec.indexMin = 0; 155 spec.indexMax = 0; 156 spec.instanceCount = 1; 157 158 spec.attribs.resize(1); 159 160 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 161 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 162 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 163 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 164 spec.attribs[0].componentCount = 2; 165 spec.attribs[0].offset = 0; 166 spec.attribs[0].stride = 0; 167 spec.attribs[0].normalize = false; 168 spec.attribs[0].instanceDivisor = 0; 169 spec.attribs[0].useDefaultAttribute = false; 170 171 addTestIterations(test, spec, TYPE_DRAW_COUNT); 172 173 this->addChild(test); 174 } 175 176 // Multiple attribute 177 { 178 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays"); 179 gls::DrawTestSpec spec; 180 181 spec.apiType = glu::ApiType::es(2,0); 182 spec.primitive = m_primitive; 183 spec.primitiveCount = 0; 184 spec.drawMethod = m_method; 185 spec.indexType = m_indexType; 186 spec.indexPointerOffset = 0; 187 spec.indexStorage = m_indexStorage; 188 spec.first = 0; 189 spec.indexMin = 0; 190 spec.indexMax = 0; 191 spec.instanceCount = 1; 192 193 spec.attribs.resize(2); 194 195 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 196 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 197 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 198 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 199 spec.attribs[0].componentCount = 4; 200 spec.attribs[0].offset = 0; 201 spec.attribs[0].stride = 0; 202 spec.attribs[0].normalize = false; 203 spec.attribs[0].instanceDivisor = 0; 204 spec.attribs[0].useDefaultAttribute = false; 205 206 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 207 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 208 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER; 209 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 210 spec.attribs[1].componentCount = 2; 211 spec.attribs[1].offset = 0; 212 spec.attribs[1].stride = 0; 213 spec.attribs[1].normalize = false; 214 spec.attribs[1].instanceDivisor = 0; 215 spec.attribs[1].useDefaultAttribute = false; 216 217 addTestIterations(test, spec, TYPE_DRAW_COUNT); 218 219 this->addChild(test); 220 } 221 222 // Multiple attribute, second one default. 223 { 224 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*."); 225 gls::DrawTestSpec spec; 226 227 spec.apiType = glu::ApiType::es(2,0); 228 spec.primitive = m_primitive; 229 spec.primitiveCount = 5; 230 spec.drawMethod = m_method; 231 spec.indexType = m_indexType; 232 spec.indexPointerOffset = 0; 233 spec.indexStorage = m_indexStorage; 234 spec.first = 0; 235 spec.indexMin = 0; 236 spec.indexMax = 0; 237 spec.instanceCount = 1; 238 239 spec.attribs.resize(2); 240 241 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 242 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 243 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 244 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 245 spec.attribs[0].componentCount = 2; 246 spec.attribs[0].offset = 0; 247 spec.attribs[0].stride = 0; 248 spec.attribs[0].normalize = false; 249 spec.attribs[0].instanceDivisor = 0; 250 spec.attribs[0].useDefaultAttribute = false; 251 252 struct IOPair 253 { 254 gls::DrawTestSpec::InputType input; 255 gls::DrawTestSpec::OutputType output; 256 int componentCount; 257 } iopairs[] = 258 { 259 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2, 4 }, 260 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC4, 2 }, 261 }; 262 263 for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx) 264 { 265 const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output); 266 267 spec.attribs[1].inputType = iopairs[ioNdx].input; 268 spec.attribs[1].outputType = iopairs[ioNdx].output; 269 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER; 270 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 271 spec.attribs[1].componentCount = iopairs[ioNdx].componentCount; 272 spec.attribs[1].offset = 0; 273 spec.attribs[1].stride = 0; 274 spec.attribs[1].normalize = false; 275 spec.attribs[1].instanceDivisor = 0; 276 spec.attribs[1].useDefaultAttribute = true; 277 278 test->addIteration(spec, desc.c_str()); 279 } 280 281 this->addChild(test); 282 } 283 } 284 285 class IndexGroup : public TestCaseGroup 286 { 287 public: 288 IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod); 289 ~IndexGroup (void); 290 291 void init (void); 292 293 private: 294 gls::DrawTestSpec::DrawMethod m_method; 295 }; 296 297 IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod) 298 : TestCaseGroup (context, name, descr) 299 , m_method (drawMethod) 300 { 301 } 302 303 IndexGroup::~IndexGroup (void) 304 { 305 } 306 307 void IndexGroup::init (void) 308 { 309 struct IndexTest 310 { 311 gls::DrawTestSpec::Storage storage; 312 gls::DrawTestSpec::IndexType type; 313 bool aligned; 314 int offsets[3]; 315 }; 316 317 const IndexTest tests[] = 318 { 319 { gls::DrawTestSpec::STORAGE_USER, gls::DrawTestSpec::INDEXTYPE_BYTE, true, { 0, 1, -1 } }, 320 { gls::DrawTestSpec::STORAGE_USER, gls::DrawTestSpec::INDEXTYPE_SHORT, true, { 0, 2, -1 } }, 321 322 { gls::DrawTestSpec::STORAGE_USER, gls::DrawTestSpec::INDEXTYPE_SHORT, false, { 1, 3, -1 } }, 323 324 { gls::DrawTestSpec::STORAGE_BUFFER, gls::DrawTestSpec::INDEXTYPE_BYTE, true, { 0, 1, -1 } }, 325 { gls::DrawTestSpec::STORAGE_BUFFER, gls::DrawTestSpec::INDEXTYPE_SHORT, true, { 0, 2, -1 } }, 326 }; 327 328 gls::DrawTestSpec spec; 329 330 tcu::TestCaseGroup* userPtrGroup = new tcu::TestCaseGroup(m_testCtx, "user_ptr", "user pointer"); 331 tcu::TestCaseGroup* unalignedUserPtrGroup = new tcu::TestCaseGroup(m_testCtx, "unaligned_user_ptr", "unaligned user pointer"); 332 tcu::TestCaseGroup* bufferGroup = new tcu::TestCaseGroup(m_testCtx, "buffer", "buffer"); 333 334 genBasicSpec(spec, m_method); 335 336 this->addChild(userPtrGroup); 337 this->addChild(unalignedUserPtrGroup); 338 this->addChild(bufferGroup); 339 340 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx) 341 { 342 const IndexTest& indexTest = tests[testNdx]; 343 tcu::TestCaseGroup* group = (indexTest.storage == gls::DrawTestSpec::STORAGE_USER) 344 ? ((indexTest.aligned) ? (userPtrGroup) : (unalignedUserPtrGroup)) 345 : ((indexTest.aligned) ? (bufferGroup) : (DE_NULL)); 346 347 const std::string name = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type); 348 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type) + " in " + gls::DrawTestSpec::storageToString(indexTest.storage); 349 de::MovePtr<gls::DrawTest> test (new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str())); 350 351 spec.indexType = indexTest.type; 352 spec.indexStorage = indexTest.storage; 353 354 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx) 355 { 356 const std::string iterationDesc = std::string("offset ") + de::toString(indexTest.offsets[iterationNdx]); 357 spec.indexPointerOffset = indexTest.offsets[iterationNdx]; 358 test->addIteration(spec, iterationDesc.c_str()); 359 } 360 361 DE_ASSERT(spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET); 362 DE_ASSERT(spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE); 363 group->addChild(test.release()); 364 } 365 } 366 367 368 class FirstGroup : public TestCaseGroup 369 { 370 public: 371 FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod); 372 ~FirstGroup (void); 373 374 void init (void); 375 376 private: 377 gls::DrawTestSpec::DrawMethod m_method; 378 }; 379 380 FirstGroup::FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod) 381 : TestCaseGroup (context, name, descr) 382 , m_method (drawMethod) 383 { 384 } 385 386 FirstGroup::~FirstGroup (void) 387 { 388 } 389 390 void FirstGroup::init (void) 391 { 392 const int firsts[] = 393 { 394 0, 1, 17 395 }; 396 397 gls::DrawTestSpec spec; 398 genBasicSpec(spec, m_method); 399 400 for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx) 401 { 402 const std::string name = std::string("first_") + de::toString(firsts[firstNdx]); 403 const std::string desc = std::string("first ") + de::toString(firsts[firstNdx]); 404 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str()); 405 406 spec.first = firsts[firstNdx]; 407 408 addTestIterations(test, spec, TYPE_DRAW_COUNT); 409 410 this->addChild(test); 411 } 412 } 413 414 class MethodGroup : public TestCaseGroup 415 { 416 public: 417 MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod); 418 ~MethodGroup (void); 419 420 void init (void); 421 422 private: 423 gls::DrawTestSpec::DrawMethod m_method; 424 }; 425 426 MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod) 427 : TestCaseGroup (context, name, descr) 428 , m_method (drawMethod) 429 { 430 } 431 432 MethodGroup::~MethodGroup (void) 433 { 434 } 435 436 void MethodGroup::init (void) 437 { 438 const bool indexed = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED); 439 const bool hasFirst = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS) || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED); 440 441 const gls::DrawTestSpec::Primitive primitive[] = 442 { 443 gls::DrawTestSpec::PRIMITIVE_POINTS, 444 gls::DrawTestSpec::PRIMITIVE_TRIANGLES, 445 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN, 446 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP, 447 gls::DrawTestSpec::PRIMITIVE_LINES, 448 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP, 449 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP 450 }; 451 452 if (hasFirst) 453 { 454 // First-tests 455 this->addChild(new FirstGroup(m_context, "first", "First tests", m_method)); 456 } 457 458 if (indexed) 459 { 460 // Index-tests 461 if (m_method != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED) 462 this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method)); 463 } 464 465 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx) 466 { 467 const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]); 468 const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]); 469 470 this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER)); 471 } 472 } 473 474 class RandomGroup : public TestCaseGroup 475 { 476 public: 477 RandomGroup (Context& context, const char* name, const char* descr); 478 ~RandomGroup (void); 479 480 void init (void); 481 }; 482 483 template <int SIZE> 484 struct UniformWeightArray 485 { 486 float weights[SIZE]; 487 488 UniformWeightArray (void) 489 { 490 for (int i=0; i<SIZE; ++i) 491 weights[i] = 1.0f; 492 } 493 }; 494 495 RandomGroup::RandomGroup (Context& context, const char* name, const char* descr) 496 : TestCaseGroup (context, name, descr) 497 { 498 } 499 500 RandomGroup::~RandomGroup (void) 501 { 502 } 503 504 void RandomGroup::init (void) 505 { 506 const int numAttempts = 100; 507 508 static const int attribCounts[] = { 1, 2, 5 }; 509 static const float attribWeights[] = { 30, 10, 1 }; 510 static const int primitiveCounts[] = { 1, 5, 64 }; 511 static const float primitiveCountWeights[] = { 20, 10, 1 }; 512 static const int indexOffsets[] = { 0, 7, 13 }; 513 static const float indexOffsetWeights[] = { 20, 20, 1 }; 514 static const int firsts[] = { 0, 7, 13 }; 515 static const float firstWeights[] = { 20, 20, 1 }; 516 static const int offsets[] = { 0, 1, 5, 12 }; 517 static const float offsetWeights[] = { 50, 10, 10, 10 }; 518 static const int strides[] = { 0, 7, 16, 17 }; 519 static const float strideWeights[] = { 50, 10, 10, 10 }; 520 521 static const gls::DrawTestSpec::Primitive primitives[] = 522 { 523 gls::DrawTestSpec::PRIMITIVE_POINTS, 524 gls::DrawTestSpec::PRIMITIVE_TRIANGLES, 525 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN, 526 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP, 527 gls::DrawTestSpec::PRIMITIVE_LINES, 528 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP, 529 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP 530 }; 531 const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights; 532 533 static const gls::DrawTestSpec::DrawMethod drawMethods[] = 534 { 535 gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS, 536 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS, 537 }; 538 const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights; 539 540 static const gls::DrawTestSpec::IndexType indexTypes[] = 541 { 542 gls::DrawTestSpec::INDEXTYPE_BYTE, 543 gls::DrawTestSpec::INDEXTYPE_SHORT, 544 }; 545 const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights; 546 547 static const gls::DrawTestSpec::Storage storages[] = 548 { 549 gls::DrawTestSpec::STORAGE_USER, 550 gls::DrawTestSpec::STORAGE_BUFFER, 551 }; 552 const UniformWeightArray<DE_LENGTH_OF_ARRAY(storages)> storageWeights; 553 554 static const gls::DrawTestSpec::InputType inputTypes[] = 555 { 556 gls::DrawTestSpec::INPUTTYPE_FLOAT, 557 gls::DrawTestSpec::INPUTTYPE_FIXED, 558 gls::DrawTestSpec::INPUTTYPE_BYTE, 559 gls::DrawTestSpec::INPUTTYPE_SHORT, 560 gls::DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE, 561 gls::DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT 562 }; 563 const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights; 564 565 static const gls::DrawTestSpec::OutputType outputTypes[] = 566 { 567 gls::DrawTestSpec::OUTPUTTYPE_FLOAT, 568 gls::DrawTestSpec::OUTPUTTYPE_VEC2, 569 gls::DrawTestSpec::OUTPUTTYPE_VEC3, 570 gls::DrawTestSpec::OUTPUTTYPE_VEC4, 571 }; 572 const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights; 573 574 static const gls::DrawTestSpec::Usage usages[] = 575 { 576 gls::DrawTestSpec::USAGE_STATIC_DRAW, 577 gls::DrawTestSpec::USAGE_DYNAMIC_DRAW, 578 gls::DrawTestSpec::USAGE_STREAM_DRAW, 579 }; 580 const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights; 581 582 static const deUint32 blacklistedCases[]= 583 { 584 3153, //!< extremely narrow triangle, results depend on sample positions 585 }; 586 587 std::set<deUint32> insertedHashes; 588 size_t insertedCount = 0; 589 590 for (int ndx = 0; ndx < numAttempts; ++ndx) 591 { 592 de::Random random(0xc551393 + ndx); // random does not depend on previous cases 593 594 int attributeCount = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights); 595 gls::DrawTestSpec spec; 596 597 spec.apiType = glu::ApiType::es(2,0); 598 spec.primitive = random.chooseWeighted<gls::DrawTestSpec::Primitive> (DE_ARRAY_BEGIN(primitives), DE_ARRAY_END(primitives), primitiveWeights.weights); 599 spec.primitiveCount = random.chooseWeighted<int, const int*, const float*> (DE_ARRAY_BEGIN(primitiveCounts), DE_ARRAY_END(primitiveCounts), primitiveCountWeights); 600 spec.drawMethod = random.chooseWeighted<gls::DrawTestSpec::DrawMethod> (DE_ARRAY_BEGIN(drawMethods), DE_ARRAY_END(drawMethods), drawMethodWeights.weights); 601 spec.indexType = random.chooseWeighted<gls::DrawTestSpec::IndexType> (DE_ARRAY_BEGIN(indexTypes), DE_ARRAY_END(indexTypes), indexTypeWeights.weights); 602 spec.indexPointerOffset = random.chooseWeighted<int, const int*, const float*> (DE_ARRAY_BEGIN(indexOffsets), DE_ARRAY_END(indexOffsets), indexOffsetWeights); 603 spec.indexStorage = random.chooseWeighted<gls::DrawTestSpec::Storage> (DE_ARRAY_BEGIN(storages), DE_ARRAY_END(storages), storageWeights.weights); 604 spec.first = random.chooseWeighted<int, const int*, const float*> (DE_ARRAY_BEGIN(firsts), DE_ARRAY_END(firsts), firstWeights); 605 spec.indexMin = 0; 606 spec.indexMax = 0; 607 spec.instanceCount = 0; 608 609 // check spec is legal 610 if (!spec.valid()) 611 continue; 612 613 for (int attrNdx = 0; attrNdx < attributeCount;) 614 { 615 bool valid; 616 gls::DrawTestSpec::AttributeSpec attribSpec; 617 618 attribSpec.inputType = random.chooseWeighted<gls::DrawTestSpec::InputType> (DE_ARRAY_BEGIN(inputTypes), DE_ARRAY_END(inputTypes), inputTypeWeights.weights); 619 attribSpec.outputType = random.chooseWeighted<gls::DrawTestSpec::OutputType> (DE_ARRAY_BEGIN(outputTypes), DE_ARRAY_END(outputTypes), outputTypeWeights.weights); 620 attribSpec.storage = random.chooseWeighted<gls::DrawTestSpec::Storage> (DE_ARRAY_BEGIN(storages), DE_ARRAY_END(storages), storageWeights.weights); 621 attribSpec.usage = random.chooseWeighted<gls::DrawTestSpec::Usage> (DE_ARRAY_BEGIN(usages), DE_ARRAY_END(usages), usageWeights.weights); 622 attribSpec.componentCount = random.getInt(1, 4); 623 attribSpec.offset = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), offsetWeights); 624 attribSpec.stride = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(strides), DE_ARRAY_END(strides), strideWeights); 625 attribSpec.normalize = random.getBool(); 626 attribSpec.instanceDivisor = 0; 627 attribSpec.useDefaultAttribute = random.getBool(); 628 629 // check spec is legal 630 valid = attribSpec.valid(spec.apiType); 631 632 // we do not want interleaved elements. (Might result in some weird floating point values) 633 if (attribSpec.stride && attribSpec.componentCount * gls::DrawTestSpec::inputTypeSize(attribSpec.inputType) > attribSpec.stride) 634 valid = false; 635 636 // try again if not valid 637 if (valid) 638 { 639 spec.attribs.push_back(attribSpec); 640 ++attrNdx; 641 } 642 } 643 644 // Do not collapse all vertex positions to a single positions 645 if (spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS) 646 spec.attribs[0].instanceDivisor = 0; 647 648 // Is render result meaningful? 649 { 650 // Only one vertex 651 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS) 652 continue; 653 if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS) 654 continue; 655 656 // Triangle only on one axis 657 if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLES || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP) 658 { 659 if (spec.attribs[0].componentCount == 1) 660 continue; 661 if (spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_FLOAT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_INT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_UINT) 662 continue; 663 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2) 664 continue; 665 } 666 } 667 668 // Add case 669 { 670 deUint32 hash = spec.hash(); 671 for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx) 672 hash = (hash << 2) ^ (deUint32)spec.attribs[attrNdx].hash(); 673 674 if (insertedHashes.find(hash) == insertedHashes.end() && 675 !de::contains(DE_ARRAY_BEGIN(blacklistedCases), DE_ARRAY_END(blacklistedCases), hash)) 676 { 677 // Only aligned cases 678 if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET && 679 spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE) 680 this->addChild(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), spec, de::toString(insertedCount).c_str(), spec.getDesc().c_str())); 681 insertedHashes.insert(hash); 682 683 ++insertedCount; 684 } 685 } 686 } 687 } 688 689 } // anonymous 690 691 DrawTests::DrawTests (Context& context) 692 : TestCaseGroup(context, "draw", "Drawing tests") 693 { 694 } 695 696 DrawTests::~DrawTests (void) 697 { 698 } 699 700 void DrawTests::init (void) 701 { 702 // Basic 703 { 704 const gls::DrawTestSpec::DrawMethod basicMethods[] = 705 { 706 gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS, 707 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS, 708 }; 709 710 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx) 711 { 712 std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]); 713 std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]); 714 715 this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx])); 716 } 717 } 718 719 // Random 720 721 this->addChild(new RandomGroup(m_context, "random", "random draw commands.")); 722 } 723 724 } // Functional 725 } // gles2 726 } // deqp 727