1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.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 Vertex array and buffer tests 22 *//*--------------------------------------------------------------------*/ 23 24#include "es3fVertexArrayTest.hpp" 25#include "glsVertexArrayTests.hpp" 26 27#include <sstream> 28 29using namespace deqp::gls; 30 31namespace deqp 32{ 33namespace gles3 34{ 35namespace Functional 36{ 37 38class SingleVertexArrayUsageGroup : public TestCaseGroup 39{ 40public: 41 SingleVertexArrayUsageGroup (Context& context, Array::Usage usage); 42 virtual ~SingleVertexArrayUsageGroup (void); 43 44 virtual void init (void); 45 46private: 47 SingleVertexArrayUsageGroup (const SingleVertexArrayUsageGroup& other); 48 SingleVertexArrayUsageGroup& operator= (const SingleVertexArrayUsageGroup& other); 49 50 Array::Usage m_usage; 51}; 52 53SingleVertexArrayUsageGroup::SingleVertexArrayUsageGroup (Context& context, Array::Usage usage) 54 : TestCaseGroup (context, Array::usageTypeToString(usage).c_str(), Array::usageTypeToString(usage).c_str()) 55 , m_usage (usage) 56{ 57} 58 59SingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void) 60{ 61} 62 63template<class T> 64static std::string typeToString (T t) 65{ 66 std::stringstream strm; 67 strm << t; 68 return strm.str(); 69} 70 71void SingleVertexArrayUsageGroup::init (void) 72{ 73 int counts[] = {1, 256}; 74 int strides[] = {0, -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL. 75 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE}; 76 77 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 78 { 79 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 80 { 81 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 82 { 83 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]); 84 const bool aligned = (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0; 85 const std::string name = "stride" + typeToString(stride) + "_" + Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_quads" + typeToString(counts[countNdx]); 86 87 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], 88 Array::OUTPUTTYPE_VEC2, 89 Array::STORAGE_BUFFER, 90 m_usage, 91 2, 92 0, 93 stride, 94 false, 95 GLValue::getMinValue(inputTypes[inputTypeNdx]), 96 GLValue::getMaxValue(inputTypes[inputTypeNdx])); 97 98 MultiVertexArrayTest::Spec spec; 99 spec.primitive = Array::PRIMITIVE_TRIANGLES; 100 spec.drawCount = counts[countNdx]; 101 spec.first = 0; 102 spec.arrays.push_back(arraySpec); 103 104 if (aligned) 105 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 106 } 107 } 108 } 109} 110 111class SingleVertexArrayUsageTests : public TestCaseGroup 112{ 113public: 114 SingleVertexArrayUsageTests (Context& context); 115 virtual ~SingleVertexArrayUsageTests (void); 116 117 virtual void init (void); 118 119private: 120 SingleVertexArrayUsageTests (const SingleVertexArrayUsageTests& other); 121 SingleVertexArrayUsageTests& operator= (const SingleVertexArrayUsageTests& other); 122}; 123 124SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context) 125 : TestCaseGroup(context, "usages", "Single vertex atribute, usage") 126{ 127} 128 129SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void) 130{ 131} 132 133void SingleVertexArrayUsageTests::init (void) 134{ 135 // Test usage 136 Array::Usage usages[] = { Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW, Array::USAGE_STATIC_COPY, Array::USAGE_STREAM_COPY, Array::USAGE_DYNAMIC_COPY, Array::USAGE_STATIC_READ, Array::USAGE_STREAM_READ, Array::USAGE_DYNAMIC_READ }; 137 for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++) 138 { 139 addChild(new SingleVertexArrayUsageGroup(m_context, usages[usageNdx])); 140 } 141} 142 143class SingleVertexArrayStrideGroup : public TestCaseGroup 144{ 145public: 146 SingleVertexArrayStrideGroup (Context& context, Array::InputType type); 147 virtual ~SingleVertexArrayStrideGroup (void); 148 149 virtual void init (void); 150 151private: 152 SingleVertexArrayStrideGroup (const SingleVertexArrayStrideGroup& other); 153 SingleVertexArrayStrideGroup& operator= (const SingleVertexArrayStrideGroup& other); 154 155 Array::InputType m_type; 156}; 157 158SingleVertexArrayStrideGroup::SingleVertexArrayStrideGroup (Context& context, Array::InputType type) 159 : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str()) 160 , m_type (type) 161{ 162} 163 164SingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void) 165{ 166} 167 168void SingleVertexArrayStrideGroup::init (void) 169{ 170 Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER}; 171 int counts[] = {1, 256}; 172 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL. 173 174 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++) 175 { 176 for (int componentCount = 2; componentCount < 5; componentCount++) 177 { 178 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 179 { 180 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 181 { 182 const bool packed = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10; 183 const int stride = (strides[strideNdx] < 0) ? ((packed) ? (16) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]); 184 const int alignment = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type)); 185 const bool bufferUnaligned = (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % alignment) != 0; 186 187 std::string name = Array::storageToString(storages[storageNdx]) + "_stride" + typeToString(stride) + "_components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]); 188 189 if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4) 190 continue; 191 192 MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type, 193 Array::OUTPUTTYPE_VEC4, 194 storages[storageNdx], 195 Array::USAGE_DYNAMIC_DRAW, 196 componentCount, 197 0, 198 stride, 199 false, 200 GLValue::getMinValue(m_type), 201 GLValue::getMaxValue(m_type)); 202 203 MultiVertexArrayTest::Spec spec; 204 spec.primitive = Array::PRIMITIVE_TRIANGLES; 205 spec.drawCount = counts[countNdx]; 206 spec.first = 0; 207 spec.arrays.push_back(arraySpec); 208 209 if (!bufferUnaligned) 210 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 211 } 212 } 213 } 214 } 215} 216 217class SingleVertexArrayStrideTests : public TestCaseGroup 218{ 219public: 220 SingleVertexArrayStrideTests (Context& context); 221 virtual ~SingleVertexArrayStrideTests (void); 222 223 virtual void init (void); 224 225private: 226 SingleVertexArrayStrideTests (const SingleVertexArrayStrideTests& other); 227 SingleVertexArrayStrideTests& operator= (const SingleVertexArrayStrideTests& other); 228}; 229 230SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context) 231 : TestCaseGroup(context, "strides", "Single stride vertex atribute") 232{ 233} 234 235SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void) 236{ 237} 238 239void SingleVertexArrayStrideTests::init (void) 240{ 241 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED, Array::INPUTTYPE_INT_2_10_10_10 }; 242 243 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 244 { 245 addChild(new SingleVertexArrayStrideGroup(m_context, inputTypes[inputTypeNdx])); 246 } 247} 248 249class SingleVertexArrayFirstGroup : public TestCaseGroup 250{ 251public: 252 SingleVertexArrayFirstGroup (Context& context, Array::InputType type); 253 virtual ~SingleVertexArrayFirstGroup (void); 254 255 virtual void init (void); 256 257private: 258 SingleVertexArrayFirstGroup (const SingleVertexArrayFirstGroup& other); 259 SingleVertexArrayFirstGroup& operator= (const SingleVertexArrayFirstGroup& other); 260 Array::InputType m_type; 261}; 262 263SingleVertexArrayFirstGroup::SingleVertexArrayFirstGroup (Context& context, Array::InputType type) 264 : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str()) 265 , m_type (type) 266{ 267} 268 269SingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void) 270{ 271} 272 273void SingleVertexArrayFirstGroup::init (void) 274{ 275 int counts[] = {5, 256}; 276 int firsts[] = {6, 24}; 277 int offsets[] = {1, 16, 17}; 278 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL. 279 280 for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++) 281 { 282 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 283 { 284 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 285 { 286 for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++) 287 { 288 const bool packed = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10; 289 const int componentCount = (packed) ? (4) : (2); 290 const int stride = (strides[strideNdx] < 0) ? ((packed) ? (8) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]); 291 const int alignment = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type)); 292 const bool aligned = ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0); 293 std::string name = "first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]); 294 295 MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type, 296 Array::OUTPUTTYPE_VEC2, 297 Array::STORAGE_BUFFER, 298 Array::USAGE_DYNAMIC_DRAW, 299 componentCount, 300 offsets[offsetNdx], 301 stride, 302 false, 303 GLValue::getMinValue(m_type), 304 GLValue::getMaxValue(m_type)); 305 306 MultiVertexArrayTest::Spec spec; 307 spec.primitive = Array::PRIMITIVE_TRIANGLES; 308 spec.drawCount = counts[countNdx]; 309 spec.first = firsts[firstNdx]; 310 spec.arrays.push_back(arraySpec); 311 312 if (aligned) 313 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 314 } 315 } 316 } 317 } 318} 319 320class SingleVertexArrayFirstTests : public TestCaseGroup 321{ 322public: 323 SingleVertexArrayFirstTests (Context& context); 324 virtual ~SingleVertexArrayFirstTests (void); 325 326 virtual void init (void); 327 328private: 329 SingleVertexArrayFirstTests (const SingleVertexArrayFirstTests& other); 330 SingleVertexArrayFirstTests& operator= (const SingleVertexArrayFirstTests& other); 331}; 332 333SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context) 334 : TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays") 335{ 336} 337 338SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void) 339{ 340} 341 342void SingleVertexArrayFirstTests::init (void) 343{ 344 // Test offset with different input types, component counts and storage, Usage(?) 345 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_INT_2_10_10_10 }; 346 347 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 348 { 349 addChild(new SingleVertexArrayFirstGroup(m_context, inputTypes[inputTypeNdx])); 350 } 351} 352 353class SingleVertexArrayOffsetGroup : public TestCaseGroup 354{ 355public: 356 SingleVertexArrayOffsetGroup (Context& context, Array::InputType type); 357 virtual ~SingleVertexArrayOffsetGroup (void); 358 359 virtual void init (void); 360 361private: 362 SingleVertexArrayOffsetGroup (const SingleVertexArrayOffsetGroup& other); 363 SingleVertexArrayOffsetGroup& operator= (const SingleVertexArrayOffsetGroup& other); 364 Array::InputType m_type; 365}; 366 367SingleVertexArrayOffsetGroup::SingleVertexArrayOffsetGroup (Context& context, Array::InputType type) 368 : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str()) 369 , m_type (type) 370{ 371} 372 373SingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void) 374{ 375} 376 377void SingleVertexArrayOffsetGroup::init (void) 378{ 379 int counts[] = {1, 256}; 380 int offsets[] = {1, 4, 17, 32}; 381 int strides[] = {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL. 382 383 for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++) 384 { 385 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 386 { 387 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 388 { 389 const bool packed = m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10; 390 const int componentCount = (packed) ? (4) : (2); 391 const int stride = (strides[strideNdx] < 0 ? Array::inputTypeSize(m_type) * componentCount : strides[strideNdx]); 392 const int alignment = (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type)); 393 const bool aligned = ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0); 394 const std::string name = "offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]); 395 396 MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type, 397 Array::OUTPUTTYPE_VEC2, 398 Array::STORAGE_BUFFER, 399 Array::USAGE_DYNAMIC_DRAW, 400 componentCount, 401 offsets[offsetNdx], 402 stride, 403 false, 404 GLValue::getMinValue(m_type), 405 GLValue::getMaxValue(m_type)); 406 407 MultiVertexArrayTest::Spec spec; 408 spec.primitive = Array::PRIMITIVE_TRIANGLES; 409 spec.drawCount = counts[countNdx]; 410 spec.first = 0; 411 spec.arrays.push_back(arraySpec); 412 413 if (aligned) 414 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 415 } 416 } 417 } 418} 419 420class SingleVertexArrayOffsetTests : public TestCaseGroup 421{ 422public: 423 SingleVertexArrayOffsetTests (Context& context); 424 virtual ~SingleVertexArrayOffsetTests (void); 425 426 virtual void init (void); 427 428private: 429 SingleVertexArrayOffsetTests (const SingleVertexArrayOffsetTests& other); 430 SingleVertexArrayOffsetTests& operator= (const SingleVertexArrayOffsetTests& other); 431}; 432 433SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context) 434 : TestCaseGroup(context, "offset", "Single vertex atribute offset element") 435{ 436} 437 438SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void) 439{ 440} 441 442void SingleVertexArrayOffsetTests::init (void) 443{ 444 // Test offset with different input types, component counts and storage, Usage(?) 445 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_INT_2_10_10_10 }; 446 447 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 448 { 449 addChild(new SingleVertexArrayOffsetGroup(m_context, inputTypes[inputTypeNdx])); 450 } 451} 452 453class SingleVertexArrayNormalizeGroup : public TestCaseGroup 454{ 455public: 456 SingleVertexArrayNormalizeGroup (Context& context, Array::InputType type); 457 virtual ~SingleVertexArrayNormalizeGroup (void); 458 459 virtual void init (void); 460 461private: 462 SingleVertexArrayNormalizeGroup (const SingleVertexArrayNormalizeGroup& other); 463 SingleVertexArrayNormalizeGroup& operator= (const SingleVertexArrayNormalizeGroup& other); 464 Array::InputType m_type; 465}; 466 467SingleVertexArrayNormalizeGroup::SingleVertexArrayNormalizeGroup (Context& context, Array::InputType type) 468 : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str()) 469 , m_type (type) 470{ 471} 472 473SingleVertexArrayNormalizeGroup::~SingleVertexArrayNormalizeGroup (void) 474{ 475} 476 477void SingleVertexArrayNormalizeGroup::init (void) 478{ 479 int counts[] = {1, 256}; 480 481 for (int componentCount = 2; componentCount < 5; componentCount++) 482 { 483 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 484 { 485 if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4) 486 continue; 487 488 std::string name = "components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]); 489 490 MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type, 491 Array::OUTPUTTYPE_VEC4, 492 Array::STORAGE_USER, 493 Array::USAGE_DYNAMIC_DRAW, 494 componentCount, 495 0, 496 0, 497 true, 498 GLValue::getMinValue(m_type), 499 GLValue::getMaxValue(m_type)); 500 501 MultiVertexArrayTest::Spec spec; 502 spec.primitive = Array::PRIMITIVE_TRIANGLES; 503 spec.drawCount = counts[countNdx]; 504 spec.first = 0; 505 spec.arrays.push_back(arraySpec); 506 507 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 508 } 509 } 510} 511 512class SingleVertexArrayNormalizeTests : public TestCaseGroup 513{ 514public: 515 SingleVertexArrayNormalizeTests (Context& context); 516 virtual ~SingleVertexArrayNormalizeTests (void); 517 518 virtual void init (void); 519 520private: 521 SingleVertexArrayNormalizeTests (const SingleVertexArrayNormalizeTests& other); 522 SingleVertexArrayNormalizeTests& operator= (const SingleVertexArrayNormalizeTests& other); 523}; 524 525SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context) 526 : TestCaseGroup(context, "normalize", "Single normalize vertex atribute") 527{ 528} 529 530SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void) 531{ 532} 533 534void SingleVertexArrayNormalizeTests::init (void) 535{ 536 // Test normalization with different input types, component counts and storage 537 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF , Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 }; 538 539 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 540 { 541 addChild(new SingleVertexArrayNormalizeGroup(m_context, inputTypes[inputTypeNdx])); 542 } 543} 544 545class SingleVertexArrayOutputTypeGroup : public TestCaseGroup 546{ 547public: 548 SingleVertexArrayOutputTypeGroup (Context& context, Array::InputType type); 549 virtual ~SingleVertexArrayOutputTypeGroup (void); 550 551 virtual void init (void); 552 553private: 554 SingleVertexArrayOutputTypeGroup (const SingleVertexArrayOutputTypeGroup& other); 555 SingleVertexArrayOutputTypeGroup& operator= (const SingleVertexArrayOutputTypeGroup& other); 556 Array::InputType m_type; 557}; 558 559SingleVertexArrayOutputTypeGroup::SingleVertexArrayOutputTypeGroup (Context& context, Array::InputType type) 560 : TestCaseGroup (context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str()) 561 , m_type (type) 562{ 563} 564 565SingleVertexArrayOutputTypeGroup::~SingleVertexArrayOutputTypeGroup (void) 566{ 567} 568 569void SingleVertexArrayOutputTypeGroup::init (void) 570{ 571 Array::OutputType outputTypes[] = {Array::OUTPUTTYPE_VEC2, Array::OUTPUTTYPE_VEC3, Array::OUTPUTTYPE_VEC4, Array::OUTPUTTYPE_IVEC2, Array::OUTPUTTYPE_IVEC3, Array::OUTPUTTYPE_IVEC4, Array::OUTPUTTYPE_UVEC2, Array::OUTPUTTYPE_UVEC3, Array::OUTPUTTYPE_UVEC4 }; 572 Array::Storage storages[] = {Array::STORAGE_USER}; 573 int counts[] = {1, 256}; 574 575 for (int outputTypeNdx = 0; outputTypeNdx < DE_LENGTH_OF_ARRAY(outputTypes); outputTypeNdx++) 576 { 577 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++) 578 { 579 for (int componentCount = 2; componentCount < 5; componentCount++) 580 { 581 for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++) 582 { 583 std::string name = "components" + typeToString(componentCount) + "_" + Array::outputTypeToString(outputTypes[outputTypeNdx]) + "_quads" + typeToString(counts[countNdx]); 584 585 const bool inputIsSignedInteger = m_type == Array::INPUTTYPE_INT || m_type == Array::INPUTTYPE_SHORT || m_type == Array::INPUTTYPE_BYTE; 586 const bool inputIsUnignedInteger = m_type == Array::INPUTTYPE_UNSIGNED_INT || m_type == Array::INPUTTYPE_UNSIGNED_SHORT || m_type == Array::INPUTTYPE_UNSIGNED_BYTE; 587 const bool outputIsSignedInteger = outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_IVEC4; 588 const bool outputIsUnsignedInteger = outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC2 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC3 || outputTypes[outputTypeNdx] == Array::OUTPUTTYPE_UVEC4; 589 590 // If input type is float type and output type is int type skip 591 if ((m_type == Array::INPUTTYPE_FLOAT || m_type == Array::INPUTTYPE_HALF || m_type == Array::INPUTTYPE_FIXED) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT)) 592 continue; 593 594 if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && (outputTypes[outputTypeNdx] >= Array::OUTPUTTYPE_INT)) 595 continue; 596 597 if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4) 598 continue; 599 600 // Loading signed data as unsigned causes undefined values and vice versa 601 if (inputIsSignedInteger && outputIsUnsignedInteger) 602 continue; 603 if (inputIsUnignedInteger && outputIsSignedInteger) 604 continue; 605 606 MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type, 607 outputTypes[outputTypeNdx], 608 storages[storageNdx], 609 Array::USAGE_DYNAMIC_DRAW, 610 componentCount, 611 0, 612 0, 613 false, 614 GLValue::getMinValue(m_type), 615 GLValue::getMaxValue(m_type)); 616 617 MultiVertexArrayTest::Spec spec; 618 spec.primitive = Array::PRIMITIVE_TRIANGLES; 619 spec.drawCount = counts[countNdx]; 620 spec.first = 0; 621 spec.arrays.push_back(arraySpec); 622 623 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str())); 624 } 625 } 626 } 627 } 628} 629 630class SingleVertexArrayOutputTypeTests : public TestCaseGroup 631{ 632public: 633 SingleVertexArrayOutputTypeTests (Context& context); 634 virtual ~SingleVertexArrayOutputTypeTests (void); 635 636 virtual void init (void); 637 638private: 639 SingleVertexArrayOutputTypeTests (const SingleVertexArrayOutputTypeTests& other); 640 SingleVertexArrayOutputTypeTests& operator= (const SingleVertexArrayOutputTypeTests& other); 641}; 642 643SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context) 644 : TestCaseGroup(context, "output_types", "Single output type vertex atribute") 645{ 646} 647 648SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void) 649{ 650} 651 652void SingleVertexArrayOutputTypeTests::init (void) 653{ 654 // Test output types with different input types, component counts and storage, Usage?, Precision?, float? 655 Array::InputType inputTypes[] = {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_UNSIGNED_INT, Array::INPUTTYPE_INT, Array::INPUTTYPE_HALF, Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10, Array::INPUTTYPE_INT_2_10_10_10 }; 656 657 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 658 { 659 addChild(new SingleVertexArrayOutputTypeGroup(m_context, inputTypes[inputTypeNdx])); 660 } 661} 662 663 664class SingleVertexArrayTestGroup : public TestCaseGroup 665{ 666public: 667 SingleVertexArrayTestGroup (Context& context); 668 virtual ~SingleVertexArrayTestGroup (void); 669 670 virtual void init (void); 671 672private: 673 SingleVertexArrayTestGroup (const SingleVertexArrayTestGroup& other); 674 SingleVertexArrayTestGroup& operator= (const SingleVertexArrayTestGroup& other); 675}; 676 677SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context) 678 : TestCaseGroup(context, "single_attribute", "Single vertex atribute") 679{ 680} 681 682SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void) 683{ 684} 685 686void SingleVertexArrayTestGroup::init (void) 687{ 688 addChild(new SingleVertexArrayStrideTests(m_context)); 689 addChild(new SingleVertexArrayNormalizeTests(m_context)); 690 addChild(new SingleVertexArrayOutputTypeTests(m_context)); 691 addChild(new SingleVertexArrayUsageTests(m_context)); 692 addChild(new SingleVertexArrayOffsetTests(m_context)); 693 addChild(new SingleVertexArrayFirstTests(m_context)); 694} 695 696class MultiVertexArrayCountTests : public TestCaseGroup 697{ 698public: 699 MultiVertexArrayCountTests (Context& context); 700 virtual ~MultiVertexArrayCountTests (void); 701 702 virtual void init (void); 703 704private: 705 MultiVertexArrayCountTests (const MultiVertexArrayCountTests& other); 706 MultiVertexArrayCountTests& operator= (const MultiVertexArrayCountTests& other); 707 708 std::string getTestName (const MultiVertexArrayTest::Spec& spec); 709}; 710 711MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context) 712 : TestCaseGroup(context, "attribute_count", "Attribute counts") 713{ 714} 715 716MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void) 717{ 718} 719 720std::string MultiVertexArrayCountTests::getTestName (const MultiVertexArrayTest::Spec& spec) 721{ 722 std::stringstream name; 723 name 724 << spec.arrays.size(); 725 726 return name.str(); 727} 728 729void MultiVertexArrayCountTests::init (void) 730{ 731 // Test attribute counts 732 int arrayCounts[] = {2, 3, 4, 5, 6, 7, 8}; 733 734 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) 735 { 736 MultiVertexArrayTest::Spec spec; 737 738 spec.primitive = Array::PRIMITIVE_TRIANGLES; 739 spec.drawCount = 256; 740 spec.first = 0; 741 742 for (int arrayNdx = 0; arrayNdx < arrayCounts[arrayCountNdx]; arrayNdx++) 743 { 744 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT, 745 Array::OUTPUTTYPE_VEC2, 746 Array::STORAGE_USER, 747 Array::USAGE_DYNAMIC_DRAW, 748 2, 749 0, 750 0, 751 false, 752 GLValue::getMinValue(Array::INPUTTYPE_FLOAT), 753 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT)); 754 755 spec.arrays.push_back(arraySpec); 756 } 757 758 std::string name = getTestName(spec); 759 std::string desc = getTestName(spec); 760 761 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); 762 } 763} 764 765class MultiVertexArrayStorageTests : public TestCaseGroup 766{ 767public: 768 MultiVertexArrayStorageTests (Context& context); 769 virtual ~MultiVertexArrayStorageTests (void); 770 771 virtual void init (void); 772 773private: 774 MultiVertexArrayStorageTests (const MultiVertexArrayStorageTests& other); 775 MultiVertexArrayStorageTests& operator= (const MultiVertexArrayStorageTests& other); 776 777 void addStorageCases (MultiVertexArrayTest::Spec spec, int depth); 778 std::string getTestName (const MultiVertexArrayTest::Spec& spec); 779}; 780 781MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context) 782 : TestCaseGroup(context, "storage", "Attribute storages") 783{ 784} 785 786MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void) 787{ 788} 789 790std::string MultiVertexArrayStorageTests::getTestName (const MultiVertexArrayTest::Spec& spec) 791{ 792 std::stringstream name; 793 name 794 << spec.arrays.size(); 795 796 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) 797 { 798 name 799 << "_" 800 << Array::storageToString(spec.arrays[arrayNdx].storage); 801 } 802 803 return name.str(); 804} 805 806void MultiVertexArrayStorageTests::addStorageCases (MultiVertexArrayTest::Spec spec, int depth) 807{ 808 if (depth == 0) 809 { 810 // Skip trivial case, used elsewhere 811 bool ok = false; 812 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) 813 { 814 if (spec.arrays[arrayNdx].storage != Array::STORAGE_USER) 815 { 816 ok = true; 817 break; 818 } 819 } 820 821 if (!ok) 822 return; 823 824 std::string name = getTestName(spec); 825 std::string desc = getTestName(spec); 826 827 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); 828 return; 829 } 830 831 Array::Storage storages[] = {Array::STORAGE_USER, Array::STORAGE_BUFFER}; 832 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++) 833 { 834 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT, 835 Array::OUTPUTTYPE_VEC2, 836 storages[storageNdx], 837 Array::USAGE_DYNAMIC_DRAW, 838 2, 839 0, 840 0, 841 false, 842 GLValue::getMinValue(Array::INPUTTYPE_FLOAT), 843 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT)); 844 845 MultiVertexArrayTest::Spec _spec = spec; 846 _spec.arrays.push_back(arraySpec); 847 addStorageCases(_spec, depth-1); 848 } 849} 850 851 852void MultiVertexArrayStorageTests::init (void) 853{ 854 // Test different storages 855 int arrayCounts[] = {3}; 856 857 MultiVertexArrayTest::Spec spec; 858 859 spec.primitive = Array::PRIMITIVE_TRIANGLES; 860 spec.drawCount = 256; 861 spec.first = 0; 862 863 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) 864 addStorageCases(spec, arrayCounts[arrayCountNdx]); 865} 866 867class MultiVertexArrayStrideTests : public TestCaseGroup 868{ 869public: 870 MultiVertexArrayStrideTests (Context& context); 871 virtual ~MultiVertexArrayStrideTests (void); 872 873 virtual void init (void); 874 875private: 876 MultiVertexArrayStrideTests (const MultiVertexArrayStrideTests& other); 877 MultiVertexArrayStrideTests& operator= (const MultiVertexArrayStrideTests& other); 878 879 void addStrideCases (MultiVertexArrayTest::Spec spec, int depth); 880 std::string getTestName (const MultiVertexArrayTest::Spec& spec); 881}; 882 883MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context) 884 : TestCaseGroup(context, "stride", "Strides") 885{ 886} 887 888MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void) 889{ 890} 891 892std::string MultiVertexArrayStrideTests::getTestName (const MultiVertexArrayTest::Spec& spec) 893{ 894 std::stringstream name; 895 896 name 897 << spec.arrays.size(); 898 899 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) 900 { 901 name 902 << "_" 903 << Array::inputTypeToString(spec.arrays[arrayNdx].inputType) 904 << spec.arrays[arrayNdx].componentCount << "_" 905 << spec.arrays[arrayNdx].stride; 906 } 907 908 return name.str(); 909} 910 911void MultiVertexArrayStrideTests::init (void) 912{ 913 // Test different strides, with multiple arrays, input types?? 914 int arrayCounts[] = {3}; 915 916 MultiVertexArrayTest::Spec spec; 917 918 spec.primitive = Array::PRIMITIVE_TRIANGLES; 919 spec.drawCount = 256; 920 spec.first = 0; 921 922 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) 923 addStrideCases(spec, arrayCounts[arrayCountNdx]); 924} 925 926void MultiVertexArrayStrideTests::addStrideCases (MultiVertexArrayTest::Spec spec, int depth) 927{ 928 if (depth == 0) 929 { 930 std::string name = getTestName(spec); 931 std::string desc = getTestName(spec); 932 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); 933 return; 934 } 935 936 int strides[] = {0, -1, 17, 32}; 937 938 for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++) 939 { 940 const int componentCount = 2; 941 MultiVertexArrayTest::Spec::ArraySpec arraySpec(Array::INPUTTYPE_FLOAT, 942 Array::OUTPUTTYPE_VEC2, 943 Array::STORAGE_USER, 944 Array::USAGE_DYNAMIC_DRAW, 945 componentCount, 946 0, 947 (strides[strideNdx] >= 0 ? strides[strideNdx] : componentCount * Array::inputTypeSize(Array::INPUTTYPE_FLOAT)), 948 false, 949 GLValue::getMinValue(Array::INPUTTYPE_FLOAT), 950 GLValue::getMaxValue(Array::INPUTTYPE_FLOAT)); 951 952 MultiVertexArrayTest::Spec _spec = spec; 953 _spec.arrays.push_back(arraySpec); 954 addStrideCases(_spec, depth-1); 955 } 956} 957 958class MultiVertexArrayOutputTests : public TestCaseGroup 959{ 960public: 961 MultiVertexArrayOutputTests (Context& context); 962 virtual ~MultiVertexArrayOutputTests (void); 963 964 virtual void init (void); 965 966private: 967 MultiVertexArrayOutputTests (const MultiVertexArrayOutputTests& other); 968 MultiVertexArrayOutputTests& operator= (const MultiVertexArrayOutputTests& other); 969 970 void addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth); 971 std::string getTestName (const MultiVertexArrayTest::Spec& spec); 972}; 973 974MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context) 975 : TestCaseGroup(context, "input_types", "input types") 976{ 977} 978 979MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void) 980{ 981} 982 983std::string MultiVertexArrayOutputTests::getTestName (const MultiVertexArrayTest::Spec& spec) 984{ 985 std::stringstream name; 986 987 name 988 << spec.arrays.size(); 989 990 for (int arrayNdx = 0; arrayNdx < (int)spec.arrays.size(); arrayNdx++) 991 { 992 name 993 << "_" 994 << Array::inputTypeToString(spec.arrays[arrayNdx].inputType) 995 << spec.arrays[arrayNdx].componentCount << "_" 996 << Array::outputTypeToString(spec.arrays[arrayNdx].outputType); 997 } 998 999 return name.str(); 1000} 1001 1002void MultiVertexArrayOutputTests::init (void) 1003{ 1004 // Test different input types, with multiple arrays 1005 int arrayCounts[] = {3}; 1006 1007 MultiVertexArrayTest::Spec spec; 1008 1009 spec.primitive = Array::PRIMITIVE_TRIANGLES; 1010 spec.drawCount = 256; 1011 spec.first = 0; 1012 1013 for (int arrayCountNdx = 0; arrayCountNdx < DE_LENGTH_OF_ARRAY(arrayCounts); arrayCountNdx++) 1014 addInputTypeCases(spec, arrayCounts[arrayCountNdx]); 1015} 1016 1017void MultiVertexArrayOutputTests::addInputTypeCases (MultiVertexArrayTest::Spec spec, int depth) 1018{ 1019 if (depth == 0) 1020 { 1021 std::string name = getTestName(spec); 1022 std::string desc = getTestName(spec); 1023 addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), desc.c_str())); 1024 return; 1025 } 1026 1027 Array::InputType inputTypes[] = {Array::INPUTTYPE_FIXED, Array::INPUTTYPE_BYTE, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE, Array::INPUTTYPE_UNSIGNED_SHORT}; 1028 for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++) 1029 { 1030 MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx], 1031 Array::OUTPUTTYPE_VEC2, 1032 Array::STORAGE_USER, 1033 Array::USAGE_DYNAMIC_DRAW, 1034 2, 1035 0, 1036 0, 1037 false, 1038 GLValue::getMinValue(inputTypes[inputTypeNdx]), 1039 GLValue::getMaxValue(inputTypes[inputTypeNdx])); 1040 1041 MultiVertexArrayTest::Spec _spec = spec; 1042 _spec.arrays.push_back(arraySpec); 1043 addInputTypeCases(_spec, depth-1); 1044 } 1045} 1046 1047class MultiVertexArrayTestGroup : public TestCaseGroup 1048{ 1049public: 1050 MultiVertexArrayTestGroup (Context& context); 1051 virtual ~MultiVertexArrayTestGroup (void); 1052 1053 virtual void init (void); 1054 1055private: 1056 MultiVertexArrayTestGroup (const MultiVertexArrayTestGroup& other); 1057 MultiVertexArrayTestGroup& operator= (const MultiVertexArrayTestGroup& other); 1058}; 1059 1060MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context) 1061 : TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes") 1062{ 1063} 1064 1065MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void) 1066{ 1067} 1068 1069void MultiVertexArrayTestGroup::init (void) 1070{ 1071 addChild(new MultiVertexArrayCountTests(m_context)); 1072 addChild(new MultiVertexArrayStorageTests(m_context)); 1073 addChild(new MultiVertexArrayStrideTests(m_context)); 1074 addChild(new MultiVertexArrayOutputTests(m_context)); 1075} 1076 1077VertexArrayTestGroup::VertexArrayTestGroup (Context& context) 1078 : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests") 1079{ 1080} 1081 1082VertexArrayTestGroup::~VertexArrayTestGroup (void) 1083{ 1084} 1085 1086void VertexArrayTestGroup::init (void) 1087{ 1088 addChild(new SingleVertexArrayTestGroup(m_context)); 1089 addChild(new MultiVertexArrayTestGroup(m_context)); 1090} 1091 1092} // Functional 1093} // gles3 1094} // deqp 1095