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 29 using namespace deqp::gls; 30 31 namespace deqp 32 { 33 namespace gles3 34 { 35 namespace Functional 36 { 37 38 class SingleVertexArrayUsageGroup : public TestCaseGroup 39 { 40 public: 41 SingleVertexArrayUsageGroup (Context& context, Array::Usage usage); 42 virtual ~SingleVertexArrayUsageGroup (void); 43 44 virtual void init (void); 45 46 private: 47 SingleVertexArrayUsageGroup (const SingleVertexArrayUsageGroup& other); 48 SingleVertexArrayUsageGroup& operator= (const SingleVertexArrayUsageGroup& other); 49 50 Array::Usage m_usage; 51 }; 52 53 SingleVertexArrayUsageGroup::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 59 SingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void) 60 { 61 } 62 63 template<class T> 64 static std::string typeToString (T t) 65 { 66 std::stringstream strm; 67 strm << t; 68 return strm.str(); 69 } 70 71 void 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 111 class SingleVertexArrayUsageTests : public TestCaseGroup 112 { 113 public: 114 SingleVertexArrayUsageTests (Context& context); 115 virtual ~SingleVertexArrayUsageTests (void); 116 117 virtual void init (void); 118 119 private: 120 SingleVertexArrayUsageTests (const SingleVertexArrayUsageTests& other); 121 SingleVertexArrayUsageTests& operator= (const SingleVertexArrayUsageTests& other); 122 }; 123 124 SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context) 125 : TestCaseGroup(context, "usages", "Single vertex atribute, usage") 126 { 127 } 128 129 SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void) 130 { 131 } 132 133 void 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 143 class SingleVertexArrayStrideGroup : public TestCaseGroup 144 { 145 public: 146 SingleVertexArrayStrideGroup (Context& context, Array::InputType type); 147 virtual ~SingleVertexArrayStrideGroup (void); 148 149 virtual void init (void); 150 151 private: 152 SingleVertexArrayStrideGroup (const SingleVertexArrayStrideGroup& other); 153 SingleVertexArrayStrideGroup& operator= (const SingleVertexArrayStrideGroup& other); 154 155 Array::InputType m_type; 156 }; 157 158 SingleVertexArrayStrideGroup::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 164 SingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void) 165 { 166 } 167 168 void 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 217 class SingleVertexArrayStrideTests : public TestCaseGroup 218 { 219 public: 220 SingleVertexArrayStrideTests (Context& context); 221 virtual ~SingleVertexArrayStrideTests (void); 222 223 virtual void init (void); 224 225 private: 226 SingleVertexArrayStrideTests (const SingleVertexArrayStrideTests& other); 227 SingleVertexArrayStrideTests& operator= (const SingleVertexArrayStrideTests& other); 228 }; 229 230 SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context) 231 : TestCaseGroup(context, "strides", "Single stride vertex atribute") 232 { 233 } 234 235 SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void) 236 { 237 } 238 239 void 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 249 class SingleVertexArrayFirstGroup : public TestCaseGroup 250 { 251 public: 252 SingleVertexArrayFirstGroup (Context& context, Array::InputType type); 253 virtual ~SingleVertexArrayFirstGroup (void); 254 255 virtual void init (void); 256 257 private: 258 SingleVertexArrayFirstGroup (const SingleVertexArrayFirstGroup& other); 259 SingleVertexArrayFirstGroup& operator= (const SingleVertexArrayFirstGroup& other); 260 Array::InputType m_type; 261 }; 262 263 SingleVertexArrayFirstGroup::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 269 SingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void) 270 { 271 } 272 273 void 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 320 class SingleVertexArrayFirstTests : public TestCaseGroup 321 { 322 public: 323 SingleVertexArrayFirstTests (Context& context); 324 virtual ~SingleVertexArrayFirstTests (void); 325 326 virtual void init (void); 327 328 private: 329 SingleVertexArrayFirstTests (const SingleVertexArrayFirstTests& other); 330 SingleVertexArrayFirstTests& operator= (const SingleVertexArrayFirstTests& other); 331 }; 332 333 SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context) 334 : TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays") 335 { 336 } 337 338 SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void) 339 { 340 } 341 342 void 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 353 class SingleVertexArrayOffsetGroup : public TestCaseGroup 354 { 355 public: 356 SingleVertexArrayOffsetGroup (Context& context, Array::InputType type); 357 virtual ~SingleVertexArrayOffsetGroup (void); 358 359 virtual void init (void); 360 361 private: 362 SingleVertexArrayOffsetGroup (const SingleVertexArrayOffsetGroup& other); 363 SingleVertexArrayOffsetGroup& operator= (const SingleVertexArrayOffsetGroup& other); 364 Array::InputType m_type; 365 }; 366 367 SingleVertexArrayOffsetGroup::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 373 SingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void) 374 { 375 } 376 377 void 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 420 class SingleVertexArrayOffsetTests : public TestCaseGroup 421 { 422 public: 423 SingleVertexArrayOffsetTests (Context& context); 424 virtual ~SingleVertexArrayOffsetTests (void); 425 426 virtual void init (void); 427 428 private: 429 SingleVertexArrayOffsetTests (const SingleVertexArrayOffsetTests& other); 430 SingleVertexArrayOffsetTests& operator= (const SingleVertexArrayOffsetTests& other); 431 }; 432 433 SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context) 434 : TestCaseGroup(context, "offset", "Single vertex atribute offset element") 435 { 436 } 437 438 SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void) 439 { 440 } 441 442 void 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 453 class SingleVertexArrayNormalizeGroup : public TestCaseGroup 454 { 455 public: 456 SingleVertexArrayNormalizeGroup (Context& context, Array::InputType type); 457 virtual ~SingleVertexArrayNormalizeGroup (void); 458 459 virtual void init (void); 460 461 private: 462 SingleVertexArrayNormalizeGroup (const SingleVertexArrayNormalizeGroup& other); 463 SingleVertexArrayNormalizeGroup& operator= (const SingleVertexArrayNormalizeGroup& other); 464 Array::InputType m_type; 465 }; 466 467 SingleVertexArrayNormalizeGroup::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 473 SingleVertexArrayNormalizeGroup::~SingleVertexArrayNormalizeGroup (void) 474 { 475 } 476 477 void 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 512 class SingleVertexArrayNormalizeTests : public TestCaseGroup 513 { 514 public: 515 SingleVertexArrayNormalizeTests (Context& context); 516 virtual ~SingleVertexArrayNormalizeTests (void); 517 518 virtual void init (void); 519 520 private: 521 SingleVertexArrayNormalizeTests (const SingleVertexArrayNormalizeTests& other); 522 SingleVertexArrayNormalizeTests& operator= (const SingleVertexArrayNormalizeTests& other); 523 }; 524 525 SingleVertexArrayNormalizeTests::SingleVertexArrayNormalizeTests (Context& context) 526 : TestCaseGroup(context, "normalize", "Single normalize vertex atribute") 527 { 528 } 529 530 SingleVertexArrayNormalizeTests::~SingleVertexArrayNormalizeTests (void) 531 { 532 } 533 534 void 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 545 class SingleVertexArrayOutputTypeGroup : public TestCaseGroup 546 { 547 public: 548 SingleVertexArrayOutputTypeGroup (Context& context, Array::InputType type); 549 virtual ~SingleVertexArrayOutputTypeGroup (void); 550 551 virtual void init (void); 552 553 private: 554 SingleVertexArrayOutputTypeGroup (const SingleVertexArrayOutputTypeGroup& other); 555 SingleVertexArrayOutputTypeGroup& operator= (const SingleVertexArrayOutputTypeGroup& other); 556 Array::InputType m_type; 557 }; 558 559 SingleVertexArrayOutputTypeGroup::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 565 SingleVertexArrayOutputTypeGroup::~SingleVertexArrayOutputTypeGroup (void) 566 { 567 } 568 569 void 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 630 class SingleVertexArrayOutputTypeTests : public TestCaseGroup 631 { 632 public: 633 SingleVertexArrayOutputTypeTests (Context& context); 634 virtual ~SingleVertexArrayOutputTypeTests (void); 635 636 virtual void init (void); 637 638 private: 639 SingleVertexArrayOutputTypeTests (const SingleVertexArrayOutputTypeTests& other); 640 SingleVertexArrayOutputTypeTests& operator= (const SingleVertexArrayOutputTypeTests& other); 641 }; 642 643 SingleVertexArrayOutputTypeTests::SingleVertexArrayOutputTypeTests (Context& context) 644 : TestCaseGroup(context, "output_types", "Single output type vertex atribute") 645 { 646 } 647 648 SingleVertexArrayOutputTypeTests::~SingleVertexArrayOutputTypeTests (void) 649 { 650 } 651 652 void 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 664 class SingleVertexArrayTestGroup : public TestCaseGroup 665 { 666 public: 667 SingleVertexArrayTestGroup (Context& context); 668 virtual ~SingleVertexArrayTestGroup (void); 669 670 virtual void init (void); 671 672 private: 673 SingleVertexArrayTestGroup (const SingleVertexArrayTestGroup& other); 674 SingleVertexArrayTestGroup& operator= (const SingleVertexArrayTestGroup& other); 675 }; 676 677 SingleVertexArrayTestGroup::SingleVertexArrayTestGroup (Context& context) 678 : TestCaseGroup(context, "single_attribute", "Single vertex atribute") 679 { 680 } 681 682 SingleVertexArrayTestGroup::~SingleVertexArrayTestGroup (void) 683 { 684 } 685 686 void 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 696 class MultiVertexArrayCountTests : public TestCaseGroup 697 { 698 public: 699 MultiVertexArrayCountTests (Context& context); 700 virtual ~MultiVertexArrayCountTests (void); 701 702 virtual void init (void); 703 704 private: 705 MultiVertexArrayCountTests (const MultiVertexArrayCountTests& other); 706 MultiVertexArrayCountTests& operator= (const MultiVertexArrayCountTests& other); 707 708 std::string getTestName (const MultiVertexArrayTest::Spec& spec); 709 }; 710 711 MultiVertexArrayCountTests::MultiVertexArrayCountTests (Context& context) 712 : TestCaseGroup(context, "attribute_count", "Attribute counts") 713 { 714 } 715 716 MultiVertexArrayCountTests::~MultiVertexArrayCountTests (void) 717 { 718 } 719 720 std::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 729 void 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 765 class MultiVertexArrayStorageTests : public TestCaseGroup 766 { 767 public: 768 MultiVertexArrayStorageTests (Context& context); 769 virtual ~MultiVertexArrayStorageTests (void); 770 771 virtual void init (void); 772 773 private: 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 781 MultiVertexArrayStorageTests::MultiVertexArrayStorageTests (Context& context) 782 : TestCaseGroup(context, "storage", "Attribute storages") 783 { 784 } 785 786 MultiVertexArrayStorageTests::~MultiVertexArrayStorageTests (void) 787 { 788 } 789 790 std::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 806 void 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 852 void 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 867 class MultiVertexArrayStrideTests : public TestCaseGroup 868 { 869 public: 870 MultiVertexArrayStrideTests (Context& context); 871 virtual ~MultiVertexArrayStrideTests (void); 872 873 virtual void init (void); 874 875 private: 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 883 MultiVertexArrayStrideTests::MultiVertexArrayStrideTests (Context& context) 884 : TestCaseGroup(context, "stride", "Strides") 885 { 886 } 887 888 MultiVertexArrayStrideTests::~MultiVertexArrayStrideTests (void) 889 { 890 } 891 892 std::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 911 void 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 926 void 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 958 class MultiVertexArrayOutputTests : public TestCaseGroup 959 { 960 public: 961 MultiVertexArrayOutputTests (Context& context); 962 virtual ~MultiVertexArrayOutputTests (void); 963 964 virtual void init (void); 965 966 private: 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 974 MultiVertexArrayOutputTests::MultiVertexArrayOutputTests (Context& context) 975 : TestCaseGroup(context, "input_types", "input types") 976 { 977 } 978 979 MultiVertexArrayOutputTests::~MultiVertexArrayOutputTests (void) 980 { 981 } 982 983 std::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 1002 void 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 1017 void 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 1047 class MultiVertexArrayTestGroup : public TestCaseGroup 1048 { 1049 public: 1050 MultiVertexArrayTestGroup (Context& context); 1051 virtual ~MultiVertexArrayTestGroup (void); 1052 1053 virtual void init (void); 1054 1055 private: 1056 MultiVertexArrayTestGroup (const MultiVertexArrayTestGroup& other); 1057 MultiVertexArrayTestGroup& operator= (const MultiVertexArrayTestGroup& other); 1058 }; 1059 1060 MultiVertexArrayTestGroup::MultiVertexArrayTestGroup (Context& context) 1061 : TestCaseGroup(context, "multiple_attributes", "Multiple vertex atributes") 1062 { 1063 } 1064 1065 MultiVertexArrayTestGroup::~MultiVertexArrayTestGroup (void) 1066 { 1067 } 1068 1069 void 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 1077 VertexArrayTestGroup::VertexArrayTestGroup (Context& context) 1078 : TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests") 1079 { 1080 } 1081 1082 VertexArrayTestGroup::~VertexArrayTestGroup (void) 1083 { 1084 } 1085 1086 void 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