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 31 using std::string; 32 using std::vector; 33 34 namespace deqp 35 { 36 namespace gles3 37 { 38 namespace Functional 39 { 40 41 using gls::UniformBlockCase; 42 using gls::RandomUniformBlockCase; 43 using namespace gls::ub; 44 45 static 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 57 class BlockBasicTypeCase : public UniformBlockCase 58 { 59 public: 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 75 static 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 84 class BlockSingleStructCase : public UniformBlockCase 85 { 86 public: 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 112 private: 113 deUint32 m_layoutFlags; 114 int m_numInstances; 115 }; 116 117 class BlockSingleStructArrayCase : public UniformBlockCase 118 { 119 public: 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 147 private: 148 deUint32 m_layoutFlags; 149 int m_numInstances; 150 }; 151 152 class BlockSingleNestedStructCase : public UniformBlockCase 153 { 154 public: 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 187 private: 188 deUint32 m_layoutFlags; 189 int m_numInstances; 190 }; 191 192 class BlockSingleNestedStructArrayCase : public UniformBlockCase 193 { 194 public: 195 BlockSingleNestedStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances) 196 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 197 , m_layoutFlags (layoutFlags) 198 , m_numInstances (numInstances) 199 { 200 } 201 202 void init (void) 203 { 204 StructType& typeS = m_interface.allocStruct("S"); 205 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH)); 206 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4)); 207 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH); 208 209 StructType& typeT = m_interface.allocStruct("T"); 210 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)); 211 typeT.addMember("b", VarType(VarType(&typeS), 3)); 212 213 UniformBlock& block = m_interface.allocBlock("Block"); 214 block.addUniform(Uniform("s", VarType(&typeS), 0)); 215 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH)); 216 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0)); 217 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0)); 218 block.setFlags(m_layoutFlags); 219 220 if (m_numInstances > 0) 221 { 222 block.setInstanceName("block"); 223 block.setArraySize(m_numInstances); 224 } 225 } 226 227 private: 228 deUint32 m_layoutFlags; 229 int m_numInstances; 230 }; 231 232 class BlockMultiBasicTypesCase : public UniformBlockCase 233 { 234 public: 235 BlockMultiBasicTypesCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances) 236 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 237 , m_flagsA (flagsA) 238 , m_flagsB (flagsB) 239 , m_numInstances (numInstances) 240 { 241 } 242 243 void init (void) 244 { 245 UniformBlock& blockA = m_interface.allocBlock("BlockA"); 246 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH))); 247 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH)); 248 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM))); 249 blockA.setInstanceName("blockA"); 250 blockA.setFlags(m_flagsA); 251 252 UniformBlock& blockB = m_interface.allocBlock("BlockB"); 253 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM))); 254 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW))); 255 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH)); 256 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0))); 257 blockB.setInstanceName("blockB"); 258 blockB.setFlags(m_flagsB); 259 260 if (m_numInstances > 0) 261 { 262 blockA.setArraySize(m_numInstances); 263 blockB.setArraySize(m_numInstances); 264 } 265 } 266 267 private: 268 deUint32 m_flagsA; 269 deUint32 m_flagsB; 270 int m_numInstances; 271 }; 272 273 class BlockMultiNestedStructCase : public UniformBlockCase 274 { 275 public: 276 BlockMultiNestedStructCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances) 277 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode) 278 , m_flagsA (flagsA) 279 , m_flagsB (flagsB) 280 , m_numInstances (numInstances) 281 { 282 } 283 284 void init (void) 285 { 286 StructType& typeS = m_interface.allocStruct("S"); 287 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW)); 288 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4)); 289 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH)); 290 291 StructType& typeT = m_interface.allocStruct("T"); 292 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH); 293 typeT.addMember("b", VarType(&typeS)); 294 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0)); 295 296 UniformBlock& blockA = m_interface.allocBlock("BlockA"); 297 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH))); 298 blockA.addUniform(Uniform("b", VarType(&typeS))); 299 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH)); 300 blockA.setInstanceName("blockA"); 301 blockA.setFlags(m_flagsA); 302 303 UniformBlock& blockB = m_interface.allocBlock("BlockB"); 304 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM))); 305 blockB.addUniform(Uniform("b", VarType(&typeT))); 306 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH)); 307 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0))); 308 blockB.setInstanceName("blockB"); 309 blockB.setFlags(m_flagsB); 310 311 if (m_numInstances > 0) 312 { 313 blockA.setArraySize(m_numInstances); 314 blockB.setArraySize(m_numInstances); 315 } 316 } 317 318 private: 319 deUint32 m_flagsA; 320 deUint32 m_flagsB; 321 int m_numInstances; 322 }; 323 324 UniformBlockTests::UniformBlockTests (Context& context) 325 : TestCaseGroup(context, "ubo", "Uniform Block tests") 326 { 327 } 328 329 UniformBlockTests::~UniformBlockTests (void) 330 { 331 } 332 333 void UniformBlockTests::init (void) 334 { 335 static const glu::DataType basicTypes[] = 336 { 337 glu::TYPE_FLOAT, 338 glu::TYPE_FLOAT_VEC2, 339 glu::TYPE_FLOAT_VEC3, 340 glu::TYPE_FLOAT_VEC4, 341 glu::TYPE_INT, 342 glu::TYPE_INT_VEC2, 343 glu::TYPE_INT_VEC3, 344 glu::TYPE_INT_VEC4, 345 glu::TYPE_UINT, 346 glu::TYPE_UINT_VEC2, 347 glu::TYPE_UINT_VEC3, 348 glu::TYPE_UINT_VEC4, 349 glu::TYPE_BOOL, 350 glu::TYPE_BOOL_VEC2, 351 glu::TYPE_BOOL_VEC3, 352 glu::TYPE_BOOL_VEC4, 353 glu::TYPE_FLOAT_MAT2, 354 glu::TYPE_FLOAT_MAT3, 355 glu::TYPE_FLOAT_MAT4, 356 glu::TYPE_FLOAT_MAT2X3, 357 glu::TYPE_FLOAT_MAT2X4, 358 glu::TYPE_FLOAT_MAT3X2, 359 glu::TYPE_FLOAT_MAT3X4, 360 glu::TYPE_FLOAT_MAT4X2, 361 glu::TYPE_FLOAT_MAT4X3 362 }; 363 364 static const struct 365 { 366 const char* name; 367 deUint32 flags; 368 } precisionFlags[] = 369 { 370 { "lowp", PRECISION_LOW }, 371 { "mediump", PRECISION_MEDIUM }, 372 { "highp", PRECISION_HIGH } 373 }; 374 375 static const struct 376 { 377 const char* name; 378 deUint32 flags; 379 } layoutFlags[] = 380 { 381 { "shared", LAYOUT_SHARED }, 382 { "packed", LAYOUT_PACKED }, 383 { "std140", LAYOUT_STD140 } 384 }; 385 386 static const struct 387 { 388 const char* name; 389 deUint32 flags; 390 } matrixFlags[] = 391 { 392 { "row_major", LAYOUT_ROW_MAJOR }, 393 { "column_major", LAYOUT_COLUMN_MAJOR } 394 }; 395 396 static const struct 397 { 398 const char* name; 399 UniformBlockCase::BufferMode mode; 400 } bufferModes[] = 401 { 402 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK }, 403 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE } 404 }; 405 406 // ubo.single_basic_type 407 { 408 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer"); 409 addChild(singleBasicTypeGroup); 410 411 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 412 { 413 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""); 414 singleBasicTypeGroup->addChild(layoutGroup); 415 416 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 417 { 418 glu::DataType type = basicTypes[basicTypeNdx]; 419 const char* typeName = glu::getDataTypeName(type); 420 421 if (glu::isDataTypeBoolOrBVec(type)) 422 createBlockBasicTypeCases(layoutGroup, m_context, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags); 423 else 424 { 425 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++) 426 createBlockBasicTypeCases(layoutGroup, m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(), 427 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags); 428 } 429 430 if (glu::isDataTypeMatrix(type)) 431 { 432 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 433 { 434 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++) 435 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + precisionFlags[precNdx].name + "_" + typeName).c_str(), 436 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags); 437 } 438 } 439 } 440 } 441 } 442 443 // ubo.single_basic_array 444 { 445 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer"); 446 addChild(singleBasicArrayGroup); 447 448 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 449 { 450 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""); 451 singleBasicArrayGroup->addChild(layoutGroup); 452 453 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 454 { 455 glu::DataType type = basicTypes[basicTypeNdx]; 456 const char* typeName = glu::getDataTypeName(type); 457 const int arraySize = 3; 458 459 createBlockBasicTypeCases(layoutGroup, m_context, typeName, 460 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize), 461 layoutFlags[layoutFlagNdx].flags); 462 463 if (glu::isDataTypeMatrix(type)) 464 { 465 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 466 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), 467 VarType(VarType(type, PRECISION_HIGH), arraySize), 468 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags); 469 } 470 } 471 } 472 } 473 474 // ubo.single_struct 475 { 476 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block"); 477 addChild(singleStructGroup); 478 479 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 480 { 481 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 482 singleStructGroup->addChild(modeGroup); 483 484 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 485 { 486 for (int isArray = 0; isArray < 2; isArray++) 487 { 488 std::string baseName = layoutFlags[layoutFlagNdx].name; 489 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 490 491 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 492 continue; // Doesn't make sense to add this variant. 493 494 if (isArray) 495 baseName += "_instance_array"; 496 497 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 498 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 499 500 if (!(baseFlags & LAYOUT_PACKED)) 501 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 502 } 503 } 504 } 505 } 506 507 // ubo.single_struct_array 508 { 509 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block"); 510 addChild(singleStructArrayGroup); 511 512 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 513 { 514 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 515 singleStructArrayGroup->addChild(modeGroup); 516 517 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 518 { 519 for (int isArray = 0; isArray < 2; isArray++) 520 { 521 std::string baseName = layoutFlags[layoutFlagNdx].name; 522 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 523 524 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 525 continue; // Doesn't make sense to add this variant. 526 527 if (isArray) 528 baseName += "_instance_array"; 529 530 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 531 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 532 533 if (!(baseFlags & LAYOUT_PACKED)) 534 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 535 } 536 } 537 } 538 } 539 540 // ubo.single_nested_struct 541 { 542 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block"); 543 addChild(singleNestedStructGroup); 544 545 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 546 { 547 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 548 singleNestedStructGroup->addChild(modeGroup); 549 550 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 551 { 552 for (int isArray = 0; isArray < 2; isArray++) 553 { 554 std::string baseName = layoutFlags[layoutFlagNdx].name; 555 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 556 557 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 558 continue; // Doesn't make sense to add this variant. 559 560 if (isArray) 561 baseName += "_instance_array"; 562 563 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 564 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 565 566 if (!(baseFlags & LAYOUT_PACKED)) 567 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 568 } 569 } 570 } 571 } 572 573 // ubo.single_nested_struct_array 574 { 575 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block"); 576 addChild(singleNestedStructArrayGroup); 577 578 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 579 { 580 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 581 singleNestedStructArrayGroup->addChild(modeGroup); 582 583 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 584 { 585 for (int isArray = 0; isArray < 2; isArray++) 586 { 587 std::string baseName = layoutFlags[layoutFlagNdx].name; 588 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 589 590 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 591 continue; // Doesn't make sense to add this variant. 592 593 if (isArray) 594 baseName += "_instance_array"; 595 596 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 597 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 598 599 if (!(baseFlags & LAYOUT_PACKED)) 600 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 601 } 602 } 603 } 604 } 605 606 // ubo.instance_array_basic_type 607 { 608 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array"); 609 addChild(instanceArrayBasicTypeGroup); 610 611 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 612 { 613 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""); 614 instanceArrayBasicTypeGroup->addChild(layoutGroup); 615 616 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 617 { 618 glu::DataType type = basicTypes[basicTypeNdx]; 619 const char* typeName = glu::getDataTypeName(type); 620 const int numInstances = 3; 621 622 createBlockBasicTypeCases(layoutGroup, m_context, typeName, 623 VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), 624 layoutFlags[layoutFlagNdx].flags, numInstances); 625 626 if (glu::isDataTypeMatrix(type)) 627 { 628 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 629 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), 630 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags, 631 numInstances); 632 } 633 } 634 } 635 } 636 637 // ubo.multi_basic_types 638 { 639 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types"); 640 addChild(multiBasicTypesGroup); 641 642 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 643 { 644 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 645 multiBasicTypesGroup->addChild(modeGroup); 646 647 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 648 { 649 for (int isArray = 0; isArray < 2; isArray++) 650 { 651 std::string baseName = layoutFlags[layoutFlagNdx].name; 652 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 653 654 if (isArray) 655 baseName += "_instance_array"; 656 657 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 658 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 659 660 if (!(baseFlags & LAYOUT_PACKED)) 661 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)); 662 663 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 664 } 665 } 666 } 667 } 668 669 // ubo.multi_nested_struct 670 { 671 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs"); 672 addChild(multiNestedStructGroup); 673 674 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 675 { 676 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 677 multiNestedStructGroup->addChild(modeGroup); 678 679 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 680 { 681 for (int isArray = 0; isArray < 2; isArray++) 682 { 683 std::string baseName = layoutFlags[layoutFlagNdx].name; 684 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 685 686 if (isArray) 687 baseName += "_instance_array"; 688 689 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 690 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 691 692 if (!(baseFlags & LAYOUT_PACKED)) 693 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)); 694 695 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0)); 696 } 697 } 698 } 699 } 700 701 // ubo.random 702 { 703 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS; 704 const deUint32 allLayouts = FEATURE_PACKED_LAYOUT|FEATURE_SHARED_LAYOUT|FEATURE_STD140_LAYOUT; 705 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES; 706 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS; 707 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT; 708 const deUint32 allFeatures = ~FEATURE_ARRAYS_OF_ARRAYS; 709 710 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases"); 711 addChild(randomGroup); 712 713 // Basic types. 714 createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused, 25, 0); 715 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); 716 createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50); 717 createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50); 718 719 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); 720 createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100); 721 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); 722 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); 723 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); 724 725 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 200); 726 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 250); 727 } 728 } 729 730 } // Functional 731 } // gles3 732 } // deqp 733