1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2016 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Uniform block tests. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "vktUniformBlockTests.hpp" 27 28 #include "vktUniformBlockCase.hpp" 29 #include "vktRandomUniformBlockCase.hpp" 30 31 #include "tcuCommandLine.hpp" 32 #include "deStringUtil.hpp" 33 34 namespace vkt 35 { 36 namespace ubo 37 { 38 39 namespace 40 { 41 42 class BlockBasicTypeCase : public UniformBlockCase 43 { 44 public: 45 BlockBasicTypeCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const VarType& type, deUint32 layoutFlags, int numInstances, MatrixLoadFlags matrixLoadFlag) 46 : UniformBlockCase(testCtx, name, description, BUFFERMODE_PER_BLOCK, matrixLoadFlag) 47 { 48 VarType tempType = type; 49 while (tempType.isArrayType()) 50 { 51 tempType = tempType.getElementType(); 52 } 53 if (getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_UINT16 || 54 getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_INT16 || 55 getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_FLOAT16) 56 { 57 layoutFlags |= LAYOUT_16BIT_STORAGE; 58 } 59 if (getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_UINT8 || 60 getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_INT8) 61 { 62 layoutFlags |= LAYOUT_8BIT_STORAGE; 63 } 64 65 UniformBlock& block = m_interface.allocBlock("Block"); 66 // For scalar layout tests with non-scalar types, add a scalar padding variable 67 // before "var", to make var only be scalar aligned. 68 if ((layoutFlags & LAYOUT_SCALAR) && !isDataTypeScalar(type.getBasicType())) { 69 block.addUniform(Uniform("padding", VarType(getDataTypeScalarType(tempType.getBasicType()), 0), 0)); 70 } 71 block.addUniform(Uniform("var", type, 0)); 72 73 block.setFlags(layoutFlags); 74 75 if (numInstances > 0) 76 { 77 block.setArraySize(numInstances); 78 block.setInstanceName("block"); 79 } 80 81 init(); 82 } 83 }; 84 85 void createBlockBasicTypeCases (tcu::TestCaseGroup& group, tcu::TestContext& testCtx, const std::string& name, const VarType& type, deUint32 layoutFlags, int numInstances = 0) 86 { 87 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(group.getTestContext(), name.c_str(), "")); 88 89 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex", "", type, layoutFlags|DECLARE_VERTEX, numInstances, LOAD_FULL_MATRIX)); 90 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "fragment", "", type, layoutFlags|DECLARE_FRAGMENT, numInstances, LOAD_FULL_MATRIX)); 91 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "both", "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances, LOAD_FULL_MATRIX)); 92 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex_comp_access", "", type, layoutFlags|DECLARE_VERTEX, numInstances, LOAD_MATRIX_COMPONENTS)); 93 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "fragment_comp_access", "", type, layoutFlags|DECLARE_FRAGMENT, numInstances, LOAD_MATRIX_COMPONENTS)); 94 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "both_comp_access", "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances, LOAD_MATRIX_COMPONENTS)); 95 96 group.addChild(typeGroup.release()); 97 } 98 99 class BlockSingleStructCase : public UniformBlockCase 100 { 101 public: 102 BlockSingleStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag) 103 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag) 104 { 105 StructType& typeS = m_interface.allocStruct("S"); 106 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused. 107 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4)); 108 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH)); 109 110 UniformBlock& block = m_interface.allocBlock("Block"); 111 block.addUniform(Uniform("s", VarType(&typeS), 0)); 112 block.setFlags(layoutFlags); 113 114 if (numInstances > 0) 115 { 116 block.setInstanceName("block"); 117 block.setArraySize(numInstances); 118 } 119 120 init(); 121 } 122 }; 123 124 class BlockSingleStructArrayCase : public UniformBlockCase 125 { 126 public: 127 BlockSingleStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag) 128 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag) 129 { 130 StructType& typeS = m_interface.allocStruct("S"); 131 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); 132 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4)); 133 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH)); 134 135 UniformBlock& block = m_interface.allocBlock("Block"); 136 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW))); 137 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3))); 138 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM))); 139 block.setFlags(layoutFlags); 140 141 if (numInstances > 0) 142 { 143 block.setInstanceName("block"); 144 block.setArraySize(numInstances); 145 } 146 147 init(); 148 } 149 }; 150 151 class BlockSingleNestedStructCase : public UniformBlockCase 152 { 153 public: 154 BlockSingleNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag) 155 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag) 156 { 157 StructType& typeS = m_interface.allocStruct("S"); 158 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH)); 159 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4)); 160 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH); 161 162 StructType& typeT = m_interface.allocStruct("T"); 163 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)); 164 typeT.addMember("b", VarType(&typeS)); 165 166 UniformBlock& block = m_interface.allocBlock("Block"); 167 block.addUniform(Uniform("s", VarType(&typeS), 0)); 168 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH)); 169 block.addUniform(Uniform("t", VarType(&typeT), 0)); 170 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0)); 171 block.setFlags(layoutFlags); 172 173 if (numInstances > 0) 174 { 175 block.setInstanceName("block"); 176 block.setArraySize(numInstances); 177 } 178 179 init(); 180 } 181 }; 182 183 class BlockSingleNestedStructArrayCase : public UniformBlockCase 184 { 185 public: 186 BlockSingleNestedStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag) 187 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag) 188 { 189 StructType& typeS = m_interface.allocStruct("S"); 190 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH)); 191 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4)); 192 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH); 193 194 StructType& typeT = m_interface.allocStruct("T"); 195 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)); 196 typeT.addMember("b", VarType(VarType(&typeS), 3)); 197 198 UniformBlock& block = m_interface.allocBlock("Block"); 199 block.addUniform(Uniform("s", VarType(&typeS), 0)); 200 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH)); 201 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0)); 202 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0)); 203 block.setFlags(layoutFlags); 204 205 if (numInstances > 0) 206 { 207 block.setInstanceName("block"); 208 block.setArraySize(numInstances); 209 } 210 211 init(); 212 } 213 }; 214 215 class BlockMultiBasicTypesCase : public UniformBlockCase 216 { 217 public: 218 BlockMultiBasicTypesCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag) 219 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag) 220 { 221 UniformBlock& blockA = m_interface.allocBlock("BlockA"); 222 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH))); 223 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH)); 224 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM))); 225 blockA.setInstanceName("blockA"); 226 blockA.setFlags(flagsA); 227 228 UniformBlock& blockB = m_interface.allocBlock("BlockB"); 229 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM))); 230 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW))); 231 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH)); 232 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0))); 233 blockB.setInstanceName("blockB"); 234 blockB.setFlags(flagsB); 235 236 if (numInstances > 0) 237 { 238 blockA.setArraySize(numInstances); 239 blockB.setArraySize(numInstances); 240 } 241 242 init(); 243 } 244 }; 245 246 class BlockMultiNestedStructCase : public UniformBlockCase 247 { 248 public: 249 BlockMultiNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag) 250 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag) 251 { 252 StructType& typeS = m_interface.allocStruct("S"); 253 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW)); 254 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4)); 255 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH)); 256 257 StructType& typeT = m_interface.allocStruct("T"); 258 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH); 259 typeT.addMember("b", VarType(&typeS)); 260 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0)); 261 262 UniformBlock& blockA = m_interface.allocBlock("BlockA"); 263 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH))); 264 blockA.addUniform(Uniform("b", VarType(&typeS))); 265 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH)); 266 blockA.setInstanceName("blockA"); 267 blockA.setFlags(flagsA); 268 269 UniformBlock& blockB = m_interface.allocBlock("BlockB"); 270 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM))); 271 blockB.addUniform(Uniform("b", VarType(&typeT))); 272 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH)); 273 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0))); 274 blockB.setInstanceName("blockB"); 275 blockB.setFlags(flagsB); 276 277 if (numInstances > 0) 278 { 279 blockA.setArraySize(numInstances); 280 blockB.setArraySize(numInstances); 281 } 282 283 init(); 284 } 285 }; 286 287 class Block2LevelStructArrayCase : public UniformBlockCase 288 { 289 public: 290 Block2LevelStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag) 291 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag) 292 , m_layoutFlags (layoutFlags) 293 , m_numInstances (numInstances) 294 { 295 StructType& typeS = m_interface.allocStruct("S"); 296 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), UNUSED_BOTH); 297 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 4)); 298 typeS.addMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW)); 299 300 UniformBlock& block = m_interface.allocBlock("Block"); 301 block.addUniform(Uniform("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM))); 302 block.addUniform(Uniform("s", VarType(VarType(VarType(&typeS), 3), 2))); 303 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM))); 304 block.setFlags(m_layoutFlags); 305 306 if (m_numInstances > 0) 307 { 308 block.setInstanceName("block"); 309 block.setArraySize(m_numInstances); 310 } 311 312 init(); 313 } 314 315 private: 316 deUint32 m_layoutFlags; 317 int m_numInstances; 318 }; 319 320 class LinkByBindingCase : public UniformBlockCase 321 { 322 public: 323 LinkByBindingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, int numInstances) 324 : UniformBlockCase (testCtx, name, description, bufferMode, LOAD_FULL_MATRIX) 325 { 326 UniformBlock& blockA = m_interface.allocBlock("TestBlock"); 327 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH))); 328 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH)); 329 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM))); 330 blockA.setFlags(LAYOUT_STD140|DECLARE_VERTEX); 331 332 UniformBlock& blockB = m_interface.allocBlock("TestBlock"); 333 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM))); 334 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW))); 335 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH)); 336 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0))); 337 blockB.setFlags(LAYOUT_STD140|DECLARE_FRAGMENT); 338 339 if (numInstances > 0) 340 { 341 blockA.setInstanceName("testBlock"); 342 blockA.setArraySize(numInstances); 343 blockB.setInstanceName("testBlock"); 344 blockB.setArraySize(numInstances); 345 } 346 347 init(); 348 } 349 }; 350 351 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed) 352 { 353 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName, description); 354 parentGroup->addChild(group); 355 356 baseSeed += (deUint32)testCtx.getCommandLine().getBaseSeed(); 357 358 for (int ndx = 0; ndx < numCases; ndx++) 359 group->addChild(new RandomUniformBlockCase(testCtx, de::toString(ndx), "", bufferMode, features, (deUint32)ndx + baseSeed)); 360 } 361 362 // UniformBlockTests 363 364 class UniformBlockTests : public tcu::TestCaseGroup 365 { 366 public: 367 UniformBlockTests (tcu::TestContext& testCtx); 368 ~UniformBlockTests (void); 369 370 void init (void); 371 372 private: 373 UniformBlockTests (const UniformBlockTests& other); 374 UniformBlockTests& operator= (const UniformBlockTests& other); 375 }; 376 377 UniformBlockTests::UniformBlockTests (tcu::TestContext& testCtx) 378 : TestCaseGroup(testCtx, "ubo", "Uniform Block tests") 379 { 380 } 381 382 UniformBlockTests::~UniformBlockTests (void) 383 { 384 } 385 386 void UniformBlockTests::init (void) 387 { 388 static const glu::DataType basicTypes[] = 389 { 390 glu::TYPE_FLOAT, 391 glu::TYPE_FLOAT_VEC2, 392 glu::TYPE_FLOAT_VEC3, 393 glu::TYPE_FLOAT_VEC4, 394 glu::TYPE_INT, 395 glu::TYPE_INT_VEC2, 396 glu::TYPE_INT_VEC3, 397 glu::TYPE_INT_VEC4, 398 glu::TYPE_UINT, 399 glu::TYPE_UINT_VEC2, 400 glu::TYPE_UINT_VEC3, 401 glu::TYPE_UINT_VEC4, 402 glu::TYPE_BOOL, 403 glu::TYPE_BOOL_VEC2, 404 glu::TYPE_BOOL_VEC3, 405 glu::TYPE_BOOL_VEC4, 406 glu::TYPE_FLOAT_MAT2, 407 glu::TYPE_FLOAT_MAT3, 408 glu::TYPE_FLOAT_MAT4, 409 glu::TYPE_FLOAT_MAT2X3, 410 glu::TYPE_FLOAT_MAT2X4, 411 glu::TYPE_FLOAT_MAT3X2, 412 glu::TYPE_FLOAT_MAT3X4, 413 glu::TYPE_FLOAT_MAT4X2, 414 glu::TYPE_FLOAT_MAT4X3, 415 glu::TYPE_UINT8, 416 glu::TYPE_UINT8_VEC2, 417 glu::TYPE_UINT8_VEC3, 418 glu::TYPE_UINT8_VEC4, 419 glu::TYPE_INT8, 420 glu::TYPE_INT8_VEC2, 421 glu::TYPE_INT8_VEC3, 422 glu::TYPE_INT8_VEC4, 423 glu::TYPE_UINT16, 424 glu::TYPE_UINT16_VEC2, 425 glu::TYPE_UINT16_VEC3, 426 glu::TYPE_UINT16_VEC4, 427 glu::TYPE_INT16, 428 glu::TYPE_INT16_VEC2, 429 glu::TYPE_INT16_VEC3, 430 glu::TYPE_INT16_VEC4, 431 glu::TYPE_FLOAT16, 432 glu::TYPE_FLOAT16_VEC2, 433 glu::TYPE_FLOAT16_VEC3, 434 glu::TYPE_FLOAT16_VEC4, 435 }; 436 437 static const struct 438 { 439 const std::string name; 440 deUint32 flags; 441 } precisionFlags[] = 442 { 443 // TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision? 444 { "lowp", PRECISION_LOW }, 445 { "mediump", PRECISION_MEDIUM }, 446 { "highp", PRECISION_HIGH } 447 }; 448 449 static const struct 450 { 451 const char* name; 452 deUint32 flags; 453 } layoutFlags[] = 454 { 455 { "std140", LAYOUT_STD140 }, 456 { "std430", LAYOUT_STD430 }, 457 { "scalar", LAYOUT_SCALAR } 458 }; 459 460 static const struct 461 { 462 const std::string name; 463 deUint32 flags; 464 } matrixFlags[] = 465 { 466 { "row_major", LAYOUT_ROW_MAJOR }, 467 { "column_major", LAYOUT_COLUMN_MAJOR } 468 }; 469 470 static const struct 471 { 472 const char* name; 473 UniformBlockCase::BufferMode mode; 474 } bufferModes[] = 475 { 476 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK }, 477 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE } 478 }; 479 480 // ubo.2_level_array 481 { 482 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level basic array variable in single buffer"); 483 addChild(nestedArrayGroup); 484 485 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 486 { 487 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "")); 488 489 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 490 { 491 const glu::DataType type = basicTypes[basicTypeNdx]; 492 const char* const typeName = glu::getDataTypeName(type); 493 const int childSize = 4; 494 const int parentSize = 3; 495 const VarType childType (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize); 496 const VarType parentType (childType, parentSize); 497 498 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags); 499 500 if (glu::isDataTypeMatrix(type)) 501 { 502 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 503 createBlockBasicTypeCases(*layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName), 504 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags); 505 } 506 } 507 nestedArrayGroup->addChild(layoutGroup.release()); 508 } 509 } 510 511 // ubo.3_level_array 512 { 513 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer"); 514 addChild(nestedArrayGroup); 515 516 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 517 { 518 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "")); 519 520 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 521 { 522 const glu::DataType type = basicTypes[basicTypeNdx]; 523 const char* const typeName = glu::getDataTypeName(type); 524 const int childSize0 = 2; 525 const int childSize1 = 4; 526 const int parentSize = 3; 527 const VarType childType0 (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize0); 528 const VarType childType1 (childType0, childSize1); 529 const VarType parentType (childType1, parentSize); 530 531 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags); 532 533 if (glu::isDataTypeMatrix(type)) 534 { 535 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 536 createBlockBasicTypeCases(*layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName), 537 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags); 538 } 539 } 540 nestedArrayGroup->addChild(layoutGroup.release()); 541 } 542 } 543 544 // ubo.2_level_struct_array 545 { 546 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one uniform block"); 547 addChild(structArrayArrayGroup); 548 549 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 550 { 551 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 552 structArrayArrayGroup->addChild(modeGroup); 553 554 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 555 { 556 for (int isArray = 0; isArray < 2; isArray++) 557 { 558 std::string baseName = layoutFlags[layoutFlagNdx].name; 559 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 560 561 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 562 continue; // Doesn't make sense to add this variant. 563 564 if (isArray) 565 baseName += "_instance_array"; 566 567 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex"), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 568 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment"), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 569 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both"), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 570 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex_comp_access"), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 571 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment_comp_access"), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 572 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both_comp_access"), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 573 } 574 } 575 } 576 } 577 578 // ubo.single_basic_type 579 { 580 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer"); 581 addChild(singleBasicTypeGroup); 582 583 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 584 { 585 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "")); 586 587 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 588 { 589 glu::DataType type = basicTypes[basicTypeNdx]; 590 const char* const typeName = glu::getDataTypeName(type); 591 592 if (!dataTypeSupportsPrecisionModifier(type)) 593 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags); 594 } 595 596 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++) 597 { 598 de::MovePtr<tcu::TestCaseGroup> precGroup(new tcu::TestCaseGroup(m_testCtx, precisionFlags[precNdx].name.c_str(), "")); 599 600 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 601 { 602 glu::DataType type = basicTypes[basicTypeNdx]; 603 const char* const typeName = glu::getDataTypeName(type); 604 605 if (dataTypeSupportsPrecisionModifier(type)) 606 createBlockBasicTypeCases(*precGroup, m_testCtx, typeName, 607 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags); 608 609 if (glu::isDataTypeMatrix(type)) 610 { 611 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 612 { 613 createBlockBasicTypeCases(*precGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName, 614 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags); 615 616 } 617 } 618 } 619 layoutGroup->addChild(precGroup.release()); 620 } 621 singleBasicTypeGroup->addChild(layoutGroup.release()); 622 } 623 } 624 625 // ubo.single_basic_array 626 { 627 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer"); 628 addChild(singleBasicArrayGroup); 629 630 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 631 { 632 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "")); 633 634 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 635 { 636 glu::DataType type = basicTypes[basicTypeNdx]; 637 const char* const typeName = glu::getDataTypeName(type); 638 const int arraySize = 3; 639 640 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, 641 VarType(VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), arraySize), 642 layoutFlags[layoutFlagNdx].flags); 643 644 if (glu::isDataTypeMatrix(type)) 645 { 646 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 647 createBlockBasicTypeCases(*layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName, 648 VarType(VarType(type, PRECISION_HIGH), arraySize), 649 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags); 650 } 651 } 652 singleBasicArrayGroup->addChild(layoutGroup.release()); 653 } 654 } 655 656 // ubo.single_struct 657 { 658 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block"); 659 addChild(singleStructGroup); 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 singleStructGroup->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 BlockSingleStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 680 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 681 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 682 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 683 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 684 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 685 } 686 } 687 } 688 } 689 690 // ubo.single_struct_array 691 { 692 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block"); 693 addChild(singleStructArrayGroup); 694 695 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 696 { 697 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 698 singleStructArrayGroup->addChild(modeGroup); 699 700 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 701 { 702 for (int isArray = 0; isArray < 2; isArray++) 703 { 704 std::string baseName = layoutFlags[layoutFlagNdx].name; 705 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 706 707 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 708 continue; // Doesn't make sense to add this variant. 709 710 if (isArray) 711 baseName += "_instance_array"; 712 713 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 714 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 715 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 716 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 717 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 718 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 719 } 720 } 721 } 722 } 723 724 // ubo.single_nested_struct 725 { 726 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block"); 727 addChild(singleNestedStructGroup); 728 729 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 730 { 731 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 732 singleNestedStructGroup->addChild(modeGroup); 733 734 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 735 { 736 for (int isArray = 0; isArray < 2; isArray++) 737 { 738 std::string baseName = layoutFlags[layoutFlagNdx].name; 739 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 740 741 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 742 continue; // Doesn't make sense to add this variant. 743 744 if (isArray) 745 baseName += "_instance_array"; 746 747 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 748 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 749 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 750 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 751 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 752 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 753 } 754 } 755 } 756 } 757 758 // ubo.single_nested_struct_array 759 { 760 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block"); 761 addChild(singleNestedStructArrayGroup); 762 763 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 764 { 765 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 766 singleNestedStructArrayGroup->addChild(modeGroup); 767 768 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 769 { 770 for (int isArray = 0; isArray < 2; isArray++) 771 { 772 std::string baseName = layoutFlags[layoutFlagNdx].name; 773 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 774 775 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0) 776 continue; // Doesn't make sense to add this variant. 777 778 if (isArray) 779 baseName += "_instance_array"; 780 781 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 782 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 783 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 784 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 785 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 786 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 787 } 788 } 789 } 790 } 791 792 // ubo.instance_array_basic_type 793 { 794 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array"); 795 addChild(instanceArrayBasicTypeGroup); 796 797 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 798 { 799 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "")); 800 801 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++) 802 { 803 glu::DataType type = basicTypes[basicTypeNdx]; 804 const char* const typeName = glu::getDataTypeName(type); 805 const int numInstances = 3; 806 807 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, 808 VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), 809 layoutFlags[layoutFlagNdx].flags, numInstances); 810 811 if (glu::isDataTypeMatrix(type)) 812 { 813 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++) 814 createBlockBasicTypeCases(*layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName, 815 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags, 816 numInstances); 817 } 818 } 819 instanceArrayBasicTypeGroup->addChild(layoutGroup.release()); 820 } 821 } 822 823 // ubo.multi_basic_types 824 { 825 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types"); 826 addChild(multiBasicTypesGroup); 827 828 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 829 { 830 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 831 multiBasicTypesGroup->addChild(modeGroup); 832 833 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 834 { 835 for (int isArray = 0; isArray < 2; isArray++) 836 { 837 std::string baseName = layoutFlags[layoutFlagNdx].name; 838 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 839 840 if (isArray) 841 baseName += "_instance_array"; 842 843 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 844 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 845 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 846 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 847 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 848 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 849 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 850 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_mixed_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 851 } 852 } 853 } 854 } 855 856 // ubo.multi_nested_struct 857 { 858 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs"); 859 addChild(multiNestedStructGroup); 860 861 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++) 862 { 863 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, ""); 864 multiNestedStructGroup->addChild(modeGroup); 865 866 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++) 867 { 868 for (int isArray = 0; isArray < 2; isArray++) 869 { 870 std::string baseName = layoutFlags[layoutFlagNdx].name; 871 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags; 872 873 if (isArray) 874 baseName += "_instance_array"; 875 876 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 877 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 878 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 879 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX)); 880 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 881 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 882 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 883 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_mixed_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS)); 884 } 885 } 886 } 887 } 888 889 // .link_by_binding 890 { 891 tcu::TestCaseGroup* linkByBindingGroup = new tcu::TestCaseGroup(m_testCtx, "link_by_binding", "Blocks with same name but different binding"); 892 addChild(linkByBindingGroup); 893 894 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_single_instance", "", UniformBlockCase::BUFFERMODE_SINGLE, 0)); 895 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_instance_array", "", UniformBlockCase::BUFFERMODE_SINGLE, 2)); 896 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_single_instance", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 0)); 897 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_instance_array", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 2)); 898 } 899 900 // ubo.random 901 { 902 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS; 903 const deUint32 allLayouts = FEATURE_STD140_LAYOUT; 904 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES; 905 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS; 906 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT; 907 const deUint32 allFeatures = ~FEATURE_OUT_OF_ORDER_OFFSETS & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE 908 & ~FEATURE_STD430_LAYOUT & ~FEATURE_SCALAR_LAYOUT; // OOO offsets handled in a dedicated case group 909 const deUint32 allScalar = ~allLayouts & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE; 910 911 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases"); 912 addChild(randomGroup); 913 914 for (int i = 0; i < 3; ++i) 915 { 916 917 tcu::TestCaseGroup* group = randomGroup; 918 if (i == 1) 919 { 920 group = new tcu::TestCaseGroup(m_testCtx, "16bit", "16bit storage"); 921 randomGroup->addChild(group); 922 } 923 if (i == 2) 924 { 925 group = new tcu::TestCaseGroup(m_testCtx, "8bit", "8bit storage"); 926 randomGroup->addChild(group); 927 } 928 const deUint32 use16BitStorage = i == 1 ? FEATURE_16BIT_STORAGE : 0; 929 const deUint32 use8BitStorage = i == 2 ? FEATURE_8BIT_STORAGE : 0; 930 931 // Basic types. 932 createRandomCaseGroup(group, m_testCtx, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused, 25, 0); 933 createRandomCaseGroup(group, m_testCtx, "vector_types", "Scalar and vector types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|FEATURE_VECTORS, 25, 25); 934 createRandomCaseGroup(group, m_testCtx, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50); 935 createRandomCaseGroup(group, m_testCtx, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50); 936 937 createRandomCaseGroup(group, m_testCtx, "basic_instance_arrays", "Basic instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_INSTANCE_ARRAYS, 25, 75); 938 createRandomCaseGroup(group, m_testCtx, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100); 939 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS, 25, 150); 940 createRandomCaseGroup(group, m_testCtx, "nested_structs_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS, 25, 125); 941 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS, 25, 175); 942 943 createRandomCaseGroup(group, m_testCtx, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allFeatures, 50, 200); 944 createRandomCaseGroup(group, m_testCtx, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, use8BitStorage|use16BitStorage|allFeatures, 50, 250); 945 946 createRandomCaseGroup(group, m_testCtx, "all_out_of_order_offsets", "All random features, out of order member offsets", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS, 50, 300); 947 createRandomCaseGroup(group, m_testCtx, "scalar", "VK_EXT_scalar_block_layout", UniformBlockCase::BUFFERMODE_SINGLE, use8BitStorage|use16BitStorage|allScalar, 100, deInt32Hash(313)); 948 } 949 } 950 } 951 952 } // anonymous 953 954 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx) 955 { 956 return new UniformBlockTests(testCtx); 957 } 958 959 } // ubo 960 } // vkt 961