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 Uniform block tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "es3fUniformBlockTests.hpp" 25#include "glsUniformBlockCase.hpp" 26#include "glsRandomUniformBlockCase.hpp" 27#include "tcuCommandLine.hpp" 28#include "deRandom.hpp" 29#include "deStringUtil.hpp" 30 31using std::string; 32using std::vector; 33 34namespace deqp 35{ 36namespace gles3 37{ 38namespace Functional 39{ 40 41using gls::UniformBlockCase; 42using gls::RandomUniformBlockCase; 43using namespace gls::ub; 44 45static void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, Context& context, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed) 46{ 47 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description); 48 parentGroup->addChild(group); 49 50 baseSeed += (deUint32)context.getTestContext().getCommandLine().getBaseSeed(); 51 52 for (int ndx = 0; ndx < numCases; ndx++) 53 group->addChild(new RandomUniformBlockCase(context.getTestContext(), context.getRenderContext(), glu::GLSL_VERSION_300_ES, 54 de::toString(ndx).c_str(), "", bufferMode, features, (deUint32)ndx+baseSeed)); 55} 56 57class BlockBasicTypeCase : public UniformBlockCase 58{ 59public: 60 BlockBasicTypeCase (Context& context, const char* name, const char* description, const VarType& type, deUint32 layoutFlags, int numInstances) 61 : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, BUFFERMODE_PER_BLOCK) 62 { 63 UniformBlock& block = m_interface.allocBlock("Block"); 64 block.addUniform(Uniform("var", type, 0)); 65 block.setFlags(layoutFlags); 66 67 if (numInstances > 0) 68 { 69 block.setArraySize(numInstances); 70 block.setInstanceName("block"); 71 } 72 } 73}; 74 75static void createBlockBasicTypeCases (tcu::TestCaseGroup* group, Context& context, const char* name, const VarType& type, deUint32 layoutFlags, int numInstances = 0) 76{ 77 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_vertex").c_str(), "", type, layoutFlags|DECLARE_VERTEX, numInstances)); 78 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_fragment").c_str(), "", type, layoutFlags|DECLARE_FRAGMENT, numInstances)); 79 80 if (!(layoutFlags & LAYOUT_PACKED)) 81 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_both").c_str(), "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances)); 82} 83 84class BlockSingleStructCase : public UniformBlockCase 85{ 86public: 87 BlockSingleStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances) 88 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 89 , m_layoutFlags (layoutFlags) 90 , m_numInstances (numInstances) 91 { 92 } 93 94 void init (void) 95 { 96 StructType& typeS = m_interface.allocStruct("S"); 97 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused. 98 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4)); 99 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH)); 100 101 UniformBlock& block = m_interface.allocBlock("Block"); 102 block.addUniform(Uniform("s", VarType(&typeS), 0)); 103 block.setFlags(m_layoutFlags); 104 105 if (m_numInstances > 0) 106 { 107 block.setInstanceName("block"); 108 block.setArraySize(m_numInstances); 109 } 110 } 111 112private: 113 deUint32 m_layoutFlags; 114 int m_numInstances; 115}; 116 117class BlockSingleStructArrayCase : public UniformBlockCase 118{ 119public: 120 BlockSingleStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances) 121 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 122 , m_layoutFlags (layoutFlags) 123 , m_numInstances (numInstances) 124 { 125 } 126 127 void init (void) 128 { 129 StructType& typeS = m_interface.allocStruct("S"); 130 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); 131 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4)); 132 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH)); 133 134 UniformBlock& block = m_interface.allocBlock("Block"); 135 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW))); 136 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3))); 137 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM))); 138 block.setFlags(m_layoutFlags); 139 140 if (m_numInstances > 0) 141 { 142 block.setInstanceName("block"); 143 block.setArraySize(m_numInstances); 144 } 145 } 146 147private: 148 deUint32 m_layoutFlags; 149 int m_numInstances; 150}; 151 152class BlockSingleNestedStructCase : public UniformBlockCase 153{ 154public: 155 BlockSingleNestedStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances) 156 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 157 , m_layoutFlags (layoutFlags) 158 , m_numInstances (numInstances) 159 { 160 } 161 162 void init (void) 163 { 164 StructType& typeS = m_interface.allocStruct("S"); 165 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH)); 166 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4)); 167 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH); 168 169 StructType& typeT = m_interface.allocStruct("T"); 170 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)); 171 typeT.addMember("b", VarType(&typeS)); 172 173 UniformBlock& block = m_interface.allocBlock("Block"); 174 block.addUniform(Uniform("s", VarType(&typeS), 0)); 175 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH)); 176 block.addUniform(Uniform("t", VarType(&typeT), 0)); 177 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0)); 178 block.setFlags(m_layoutFlags); 179 180 if (m_numInstances > 0) 181 { 182 block.setInstanceName("block"); 183 block.setArraySize(m_numInstances); 184 } 185 } 186 187private: 188 deUint32 m_layoutFlags; 189 int m_numInstances; 190}; 191 192class BlockSingleNestedStructMixedMatrixPackingCase : public UniformBlockCase 193{ 194public: 195 BlockSingleNestedStructMixedMatrixPackingCase (Context& context, const char* name, const char* description, deUint32 blockLayoutFlags, deUint32 matrixLayoutFlags, deUint32 matrixArrayLayoutFlags, BufferMode bufferMode, int numInstances) 196 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 197 , m_blockLayoutFlags (blockLayoutFlags) 198 , m_matrixLayoutFlags (matrixLayoutFlags) 199 , m_matrixArrayLayoutFlags (matrixArrayLayoutFlags) 200 , m_numInstances (numInstances) 201 { 202 } 203 204 void init (void) 205 { 206 StructType& typeS = m_interface.allocStruct("S"); 207 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH)); 208 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4)); 209 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH); 210 211 StructType& typeT = m_interface.allocStruct("T"); 212 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)); 213 typeT.addMember("b", VarType(&typeS)); 214 215 UniformBlock& block = m_interface.allocBlock("Block"); 216 block.addUniform(Uniform("s", VarType(&typeS, m_matrixArrayLayoutFlags), 0)); 217 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH)); 218 block.addUniform(Uniform("t", VarType(&typeT, m_matrixLayoutFlags), 0)); 219 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0)); 220 block.setFlags(m_blockLayoutFlags); 221 222 if (m_numInstances > 0) 223 { 224 block.setInstanceName("block"); 225 block.setArraySize(m_numInstances); 226 } 227 } 228 229private: 230 deUint32 m_blockLayoutFlags; 231 deUint32 m_matrixLayoutFlags; 232 deUint32 m_matrixArrayLayoutFlags; 233 int m_numInstances; 234}; 235 236class BlockSingleNestedStructArrayCase : public UniformBlockCase 237{ 238public: 239 BlockSingleNestedStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances) 240 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 241 , m_layoutFlags (layoutFlags) 242 , m_numInstances (numInstances) 243 { 244 } 245 246 void init (void) 247 { 248 StructType& typeS = m_interface.allocStruct("S"); 249 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH)); 250 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4)); 251 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH); 252 253 StructType& typeT = m_interface.allocStruct("T"); 254 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)); 255 typeT.addMember("b", VarType(VarType(&typeS), 3)); 256 257 UniformBlock& block = m_interface.allocBlock("Block"); 258 block.addUniform(Uniform("s", VarType(&typeS), 0)); 259 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH)); 260 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0)); 261 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0)); 262 block.setFlags(m_layoutFlags); 263 264 if (m_numInstances > 0) 265 { 266 block.setInstanceName("block"); 267 block.setArraySize(m_numInstances); 268 } 269 } 270 271private: 272 deUint32 m_layoutFlags; 273 int m_numInstances; 274}; 275 276class BlockMultiBasicTypesCase : public UniformBlockCase 277{ 278public: 279 BlockMultiBasicTypesCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances) 280 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 281 , m_flagsA (flagsA) 282 , m_flagsB (flagsB) 283 , m_numInstances (numInstances) 284 { 285 } 286 287 void init (void) 288 { 289 UniformBlock& blockA = m_interface.allocBlock("BlockA"); 290 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH))); 291 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH)); 292 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM))); 293 blockA.setInstanceName("blockA"); 294 blockA.setFlags(m_flagsA); 295 296 UniformBlock& blockB = m_interface.allocBlock("BlockB"); 297 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM))); 298 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW))); 299 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH)); 300 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0))); 301 blockB.setInstanceName("blockB"); 302 blockB.setFlags(m_flagsB); 303 304 if (m_numInstances > 0) 305 { 306 blockA.setArraySize(m_numInstances); 307 blockB.setArraySize(m_numInstances); 308 } 309 } 310 311private: 312 deUint32 m_flagsA; 313 deUint32 m_flagsB; 314 int m_numInstances; 315}; 316 317class BlockMultiNestedStructCase : public UniformBlockCase 318{ 319public: 320 BlockMultiNestedStructCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances) 321 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 322 , m_flagsA (flagsA) 323 , m_flagsB (flagsB) 324 , m_numInstances (numInstances) 325 { 326 } 327 328 void init (void) 329 { 330 StructType& typeS = m_interface.allocStruct("S"); 331 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW)); 332 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4)); 333 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH)); 334 335 StructType& typeT = m_interface.allocStruct("T"); 336 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH); 337 typeT.addMember("b", VarType(&typeS)); 338 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0)); 339 340 UniformBlock& blockA = m_interface.allocBlock("BlockA"); 341 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH))); 342 blockA.addUniform(Uniform("b", VarType(&typeS))); 343 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH)); 344 blockA.setInstanceName("blockA"); 345 blockA.setFlags(m_flagsA); 346 347 UniformBlock& blockB = m_interface.allocBlock("BlockB"); 348 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM))); 349 blockB.addUniform(Uniform("b", VarType(&typeT))); 350 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH)); 351 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0))); 352 blockB.setInstanceName("blockB"); 353 blockB.setFlags(m_flagsB); 354 355 if (m_numInstances > 0) 356 { 357 blockA.setArraySize(m_numInstances); 358 blockB.setArraySize(m_numInstances); 359 } 360 } 361 362private: 363 deUint32 m_flagsA; 364 deUint32 m_flagsB; 365 int m_numInstances; 366}; 367 368UniformBlockTests::UniformBlockTests (Context& context) 369 : TestCaseGroup(context, "ubo", "Uniform Block tests") 370{ 371} 372 373UniformBlockTests::~UniformBlockTests (void) 374{ 375} 376 377void UniformBlockTests::init (void) 378{ 379 static const glu::DataType basicTypes[] = 380 { 381 glu::TYPE_FLOAT, 382 glu::TYPE_FLOAT_VEC2, 383 glu::TYPE_FLOAT_VEC3, 384 glu::TYPE_FLOAT_VEC4, 385 glu::TYPE_INT, 386 glu::TYPE_INT_VEC2, 387 glu::TYPE_INT_VEC3, 388 glu::TYPE_INT_VEC4, 389 glu::TYPE_UINT, 390 glu::TYPE_UINT_VEC2, 391 glu::TYPE_UINT_VEC3, 392 glu::TYPE_UINT_VEC4, 393 glu::TYPE_BOOL, 394 glu::TYPE_BOOL_VEC2, 395 glu::TYPE_BOOL_VEC3, 396 glu::TYPE_BOOL_VEC4, 397 glu::TYPE_FLOAT_MAT2, 398 glu::TYPE_FLOAT_MAT3, 399 glu::TYPE_FLOAT_MAT4, 400 glu::TYPE_FLOAT_MAT2X3, 401 glu::TYPE_FLOAT_MAT2X4, 402 glu::TYPE_FLOAT_MAT3X2, 403 glu::TYPE_FLOAT_MAT3X4, 404 glu::TYPE_FLOAT_MAT4X2, 405 glu::TYPE_FLOAT_MAT4X3 406 }; 407 408 static const struct 409 { 410 const char* name; 411 deUint32 flags; 412 } precisionFlags[] = 413 { 414 { "lowp", PRECISION_LOW }, 415 { "mediump", PRECISION_MEDIUM }, 416 { "highp", PRECISION_HIGH } 417 }; 418 419 static const struct 420 { 421 const char* name; 422 deUint32 flags; 423 } layoutFlags[] = 424 { 425 { "shared", LAYOUT_SHARED }, 426 { "packed", LAYOUT_PACKED }, 427 { "std140", LAYOUT_STD140 } 428 }; 429 430 static const struct 431 { 432 const char* name; 433 deUint32 flags; 434 } matrixFlags[] = 435 { 436 { "row_major", LAYOUT_ROW_MAJOR }, 437 { "column_major", LAYOUT_COLUMN_MAJOR } 438 }; 439 440 static const struct 441 { 442 const char* name; 443 UniformBlockCase::BufferMode mode; 444 } bufferModes[] = 445 { 446 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK }, 447 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE } 448 }; 449 450 // ubo.single_basic_type 451 { 452 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer"); 453 addChild(singleBasicTypeGroup); 454 455 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 456 { 457 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""); 458 singleBasicTypeGroup->addChild(layoutGroup); 459 460 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 461 { 462 glu::DataType type = basicTypes[basicTypeNdx]; 463 const char* typeName = glu::getDataTypeName(type); 464 465 if (glu::isDataTypeBoolOrBVec(type)) 466 createBlockBasicTypeCases(layoutGroup, m_context, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags); 467 else 468 { 469 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++) 470 createBlockBasicTypeCases(layoutGroup, m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(), 471 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags); 472 } 473 474 if (glu::isDataTypeMatrix(type)) 475 { 476 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 477 { 478 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++) 479 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + precisionFlags[precNdx].name + "_" + typeName).c_str(), 480 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags); 481 } 482 } 483 } 484 } 485 } 486 487 // ubo.single_basic_array 488 { 489 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer"); 490 addChild(singleBasicArrayGroup); 491 492 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 493 { 494 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""); 495 singleBasicArrayGroup->addChild(layoutGroup); 496 497 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 498 { 499 glu::DataType type = basicTypes[basicTypeNdx]; 500 const char* typeName = glu::getDataTypeName(type); 501 const int arraySize = 3; 502 503 createBlockBasicTypeCases(layoutGroup, m_context, typeName, 504 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize), 505 layoutFlags[layoutFlagNdx].flags); 506 507 if (glu::isDataTypeMatrix(type)) 508 { 509 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 510 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), 511 VarType(VarType(type, PRECISION_HIGH), arraySize), 512 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags); 513 } 514 } 515 } 516 } 517 518 // ubo.single_struct 519 { 520 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block"); 521 addChild(singleStructGroup); 522 523 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 524 { 525 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 526 singleStructGroup->addChild(modeGroup); 527 528 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 529 { 530 for (int isArray = 0; isArray < 2; isArray++) 531 { 532 std::string baseName = layoutFlags[layoutFlagNdx].name; 533 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 534 535 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 536 continue; // Doesn't make sense to add this variant. 537 538 if (isArray) 539 baseName += "_instance_array"; 540 541 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 542 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 543 544 if (!(baseFlags & LAYOUT_PACKED)) 545 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 546 } 547 } 548 } 549 } 550 551 // ubo.single_struct_array 552 { 553 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block"); 554 addChild(singleStructArrayGroup); 555 556 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 557 { 558 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 559 singleStructArrayGroup->addChild(modeGroup); 560 561 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 562 { 563 for (int isArray = 0; isArray < 2; isArray++) 564 { 565 std::string baseName = layoutFlags[layoutFlagNdx].name; 566 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 567 568 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 569 continue; // Doesn't make sense to add this variant. 570 571 if (isArray) 572 baseName += "_instance_array"; 573 574 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 575 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 576 577 if (!(baseFlags & LAYOUT_PACKED)) 578 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 579 } 580 } 581 } 582 } 583 584 // ubo.single_nested_struct 585 { 586 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block"); 587 addChild(singleNestedStructGroup); 588 589 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 590 { 591 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 592 singleNestedStructGroup->addChild(modeGroup); 593 594 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 595 { 596 for (int isArray = 0; isArray < 2; isArray++) 597 { 598 std::string baseName = layoutFlags[layoutFlagNdx].name; 599 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 600 601 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 602 continue; // Doesn't make sense to add this variant. 603 604 if (isArray) 605 baseName += "_instance_array"; 606 607 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 608 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 609 610 if (!(baseFlags & LAYOUT_PACKED)) 611 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 612 } 613 } 614 } 615 } 616 617 // ubo.single_nested_struct_mixed_matrix_packing 618 { 619 tcu::TestCaseGroup* singleNestedStructMixedMatrixPackingGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_mixed_matrix_packing", "Nested struct in one uniform block with a mixed matrix packing"); 620 addChild(singleNestedStructMixedMatrixPackingGroup); 621 622 for (const auto& bufferMode : bufferModes) 623 { 624 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferMode.name, ""); 625 singleNestedStructMixedMatrixPackingGroup->addChild(modeGroup); 626 627 for (const auto& layoutFlag : layoutFlags) 628 for (const auto& blockMatrixFlag : matrixFlags) 629 for (const auto& singleMatrixFlag : matrixFlags) 630 for (const auto& arrayMatrixFlag : matrixFlags) 631 for (int isArray = 0; isArray < 2; isArray++) 632 { 633 std::string baseName = layoutFlag.name; 634 deUint32 baseFlags = layoutFlag.flags; 635 deUint32 blockFlags = baseFlags | blockMatrixFlag.flags; 636 637 baseName += std::string("_block_") + blockMatrixFlag.name; 638 baseName += std::string("_matrix_") + singleMatrixFlag.name; 639 baseName += std::string("_matrixarray_") + arrayMatrixFlag.name; 640 641 if (bufferMode.mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 642 continue; // Doesn't make sense to add this variant. 643 644 if (isArray) 645 baseName += "_instance_array"; 646 647 modeGroup->addChild(new BlockSingleNestedStructMixedMatrixPackingCase(m_context, (baseName + "_vertex").c_str(), "", blockFlags | DECLARE_VERTEX, singleMatrixFlag.flags, arrayMatrixFlag.flags, bufferMode.mode, isArray ? 3 : 0)); 648 modeGroup->addChild(new BlockSingleNestedStructMixedMatrixPackingCase(m_context, (baseName + "_fragment").c_str(), "", blockFlags | DECLARE_FRAGMENT, singleMatrixFlag.flags, arrayMatrixFlag.flags, bufferMode.mode, isArray ? 3 : 0)); 649 650 if (!(baseFlags & LAYOUT_PACKED)) 651 modeGroup->addChild(new BlockSingleNestedStructMixedMatrixPackingCase(m_context, (baseName + "_both").c_str(), "", blockFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, singleMatrixFlag.flags, arrayMatrixFlag.flags, bufferMode.mode, isArray ? 3 : 0)); 652 } 653 } 654 } 655 656 // ubo.single_nested_struct_array 657 { 658 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block"); 659 addChild(singleNestedStructArrayGroup); 660 661 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 662 { 663 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 664 singleNestedStructArrayGroup->addChild(modeGroup); 665 666 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 667 { 668 for (int isArray = 0; isArray < 2; isArray++) 669 { 670 std::string baseName = layoutFlags[layoutFlagNdx].name; 671 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 672 673 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 674 continue; // Doesn't make sense to add this variant. 675 676 if (isArray) 677 baseName += "_instance_array"; 678 679 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 680 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 681 682 if (!(baseFlags & LAYOUT_PACKED)) 683 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 684 } 685 } 686 } 687 } 688 689 // ubo.instance_array_basic_type 690 { 691 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array"); 692 addChild(instanceArrayBasicTypeGroup); 693 694 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 695 { 696 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""); 697 instanceArrayBasicTypeGroup->addChild(layoutGroup); 698 699 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 700 { 701 glu::DataType type = basicTypes[basicTypeNdx]; 702 const char* typeName = glu::getDataTypeName(type); 703 const int numInstances = 3; 704 705 createBlockBasicTypeCases(layoutGroup, m_context, typeName, 706 VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), 707 layoutFlags[layoutFlagNdx].flags, numInstances); 708 709 if (glu::isDataTypeMatrix(type)) 710 { 711 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 712 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), 713 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags, 714 numInstances); 715 } 716 } 717 } 718 } 719 720 // ubo.multi_basic_types 721 { 722 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types"); 723 addChild(multiBasicTypesGroup); 724 725 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 726 { 727 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 728 multiBasicTypesGroup->addChild(modeGroup); 729 730 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 731 { 732 for (int isArray = 0; isArray < 2; isArray++) 733 { 734 std::string baseName = layoutFlags[layoutFlagNdx].name; 735 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 736 737 if (isArray) 738 baseName += "_instance_array"; 739 740 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 741 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 742 743 if (!(baseFlags & LAYOUT_PACKED)) 744 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 745 746 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 747 } 748 } 749 } 750 } 751 752 // ubo.multi_nested_struct 753 { 754 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs"); 755 addChild(multiNestedStructGroup); 756 757 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 758 { 759 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 760 multiNestedStructGroup->addChild(modeGroup); 761 762 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 763 { 764 for (int isArray = 0; isArray < 2; isArray++) 765 { 766 std::string baseName = layoutFlags[layoutFlagNdx].name; 767 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 768 769 if (isArray) 770 baseName += "_instance_array"; 771 772 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 773 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 774 775 if (!(baseFlags & LAYOUT_PACKED)) 776 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 777 778 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 779 } 780 } 781 } 782 } 783 784 // ubo.random 785 { 786 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS; 787 const deUint32 allLayouts = FEATURE_PACKED_LAYOUT|FEATURE_SHARED_LAYOUT|FEATURE_STD140_LAYOUT; 788 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES; 789 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS; 790 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT; 791 const deUint32 allFeatures = ~FEATURE_ARRAYS_OF_ARRAYS; 792 793 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases"); 794 addChild(randomGroup); 795 796 // Basic types. 797 createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused, 25, 0); 798 createRandomCaseGroup(randomGroup, m_context, "vector_types", "Scalar and vector types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|FEATURE_VECTORS, 25, 25); 799 createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50); 800 createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50); 801 802 createRandomCaseGroup(randomGroup, m_context, "basic_instance_arrays", "Basic instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_INSTANCE_ARRAYS, 25, 75); 803 createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100); 804 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS, 25, 150); 805 createRandomCaseGroup(randomGroup, m_context, "nested_structs_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS, 25, 125); 806 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS, 25, 175); 807 808 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 200); 809 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 250); 810 } 811} 812 813} // Functional 814} // gles3 815} // deqp 816