1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
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
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * \brief Uniform block tests.
24 *//*--------------------------------------------------------------------*/
26 #include "vktUniformBlockTests.hpp"
28 #include "vktUniformBlockCase.hpp"
29 #include "vktRandomUniformBlockCase.hpp"
31 #include "tcuCommandLine.hpp"
32 #include "deStringUtil.hpp"
42 class BlockBasicTypeCase : public UniformBlockCase
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)
48 UniformBlock& block = m_interface.allocBlock("Block");
49 block.addUniform(Uniform("var", type, 0));
50 block.setFlags(layoutFlags);
54 block.setArraySize(numInstances);
55 block.setInstanceName("block");
62 void createBlockBasicTypeCases (tcu::TestCaseGroup& group, tcu::TestContext& testCtx, const std::string& name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
64 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(group.getTestContext(), name.c_str(), ""));
66 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex", "", type, layoutFlags|DECLARE_VERTEX, numInstances, LOAD_FULL_MATRIX));
67 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "fragment", "", type, layoutFlags|DECLARE_FRAGMENT, numInstances, LOAD_FULL_MATRIX));
68 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "both", "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances, LOAD_FULL_MATRIX));
69 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex_comp_access", "", type, layoutFlags|DECLARE_VERTEX, numInstances, LOAD_MATRIX_COMPONENTS));
70 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "fragment_comp_access", "", type, layoutFlags|DECLARE_FRAGMENT, numInstances, LOAD_MATRIX_COMPONENTS));
71 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "both_comp_access", "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances, LOAD_MATRIX_COMPONENTS));
73 group.addChild(typeGroup.release());
76 class BlockSingleStructCase : public UniformBlockCase
79 BlockSingleStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
80 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
82 StructType& typeS = m_interface.allocStruct("S");
83 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
84 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
85 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
87 UniformBlock& block = m_interface.allocBlock("Block");
88 block.addUniform(Uniform("s", VarType(&typeS), 0));
89 block.setFlags(layoutFlags);
93 block.setInstanceName("block");
94 block.setArraySize(numInstances);
101 class BlockSingleStructArrayCase : public UniformBlockCase
104 BlockSingleStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
105 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
107 StructType& typeS = m_interface.allocStruct("S");
108 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
109 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
110 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
112 UniformBlock& block = m_interface.allocBlock("Block");
113 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
114 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
115 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
116 block.setFlags(layoutFlags);
118 if (numInstances > 0)
120 block.setInstanceName("block");
121 block.setArraySize(numInstances);
128 class BlockSingleNestedStructCase : public UniformBlockCase
131 BlockSingleNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
132 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
134 StructType& typeS = m_interface.allocStruct("S");
135 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
136 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
137 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
139 StructType& typeT = m_interface.allocStruct("T");
140 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
141 typeT.addMember("b", VarType(&typeS));
143 UniformBlock& block = m_interface.allocBlock("Block");
144 block.addUniform(Uniform("s", VarType(&typeS), 0));
145 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
146 block.addUniform(Uniform("t", VarType(&typeT), 0));
147 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
148 block.setFlags(layoutFlags);
150 if (numInstances > 0)
152 block.setInstanceName("block");
153 block.setArraySize(numInstances);
160 class BlockSingleNestedStructArrayCase : public UniformBlockCase
163 BlockSingleNestedStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
164 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
166 StructType& typeS = m_interface.allocStruct("S");
167 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
168 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
169 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
171 StructType& typeT = m_interface.allocStruct("T");
172 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
173 typeT.addMember("b", VarType(VarType(&typeS), 3));
175 UniformBlock& block = m_interface.allocBlock("Block");
176 block.addUniform(Uniform("s", VarType(&typeS), 0));
177 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
178 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
179 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
180 block.setFlags(layoutFlags);
182 if (numInstances > 0)
184 block.setInstanceName("block");
185 block.setArraySize(numInstances);
192 class BlockMultiBasicTypesCase : public UniformBlockCase
195 BlockMultiBasicTypesCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
196 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
198 UniformBlock& blockA = m_interface.allocBlock("BlockA");
199 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
200 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
201 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
202 blockA.setInstanceName("blockA");
203 blockA.setFlags(flagsA);
205 UniformBlock& blockB = m_interface.allocBlock("BlockB");
206 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
207 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
208 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
209 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
210 blockB.setInstanceName("blockB");
211 blockB.setFlags(flagsB);
213 if (numInstances > 0)
215 blockA.setArraySize(numInstances);
216 blockB.setArraySize(numInstances);
223 class BlockMultiNestedStructCase : public UniformBlockCase
226 BlockMultiNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
227 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
229 StructType& typeS = m_interface.allocStruct("S");
230 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
231 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
232 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
234 StructType& typeT = m_interface.allocStruct("T");
235 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
236 typeT.addMember("b", VarType(&typeS));
237 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
239 UniformBlock& blockA = m_interface.allocBlock("BlockA");
240 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
241 blockA.addUniform(Uniform("b", VarType(&typeS)));
242 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
243 blockA.setInstanceName("blockA");
244 blockA.setFlags(flagsA);
246 UniformBlock& blockB = m_interface.allocBlock("BlockB");
247 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
248 blockB.addUniform(Uniform("b", VarType(&typeT)));
249 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
250 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
251 blockB.setInstanceName("blockB");
252 blockB.setFlags(flagsB);
254 if (numInstances > 0)
256 blockA.setArraySize(numInstances);
257 blockB.setArraySize(numInstances);
264 class Block2LevelStructArrayCase : public UniformBlockCase
267 Block2LevelStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
268 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
269 , m_layoutFlags (layoutFlags)
270 , m_numInstances (numInstances)
272 StructType& typeS = m_interface.allocStruct("S");
273 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
274 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 4));
275 typeS.addMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW));
277 UniformBlock& block = m_interface.allocBlock("Block");
278 block.addUniform(Uniform("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM)));
279 block.addUniform(Uniform("s", VarType(VarType(VarType(&typeS), 3), 2)));
280 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM)));
281 block.setFlags(m_layoutFlags);
283 if (m_numInstances > 0)
285 block.setInstanceName("block");
286 block.setArraySize(m_numInstances);
293 deUint32 m_layoutFlags;
297 class LinkByBindingCase : public UniformBlockCase
300 LinkByBindingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, int numInstances)
301 : UniformBlockCase (testCtx, name, description, bufferMode, LOAD_FULL_MATRIX)
303 UniformBlock& blockA = m_interface.allocBlock("TestBlock");
304 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
305 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
306 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
307 blockA.setFlags(LAYOUT_STD140|DECLARE_VERTEX);
309 UniformBlock& blockB = m_interface.allocBlock("TestBlock");
310 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
311 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
312 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
313 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
314 blockB.setFlags(LAYOUT_STD140|DECLARE_FRAGMENT);
316 if (numInstances > 0)
318 blockA.setInstanceName("testBlock");
319 blockA.setArraySize(numInstances);
320 blockB.setInstanceName("testBlock");
321 blockB.setArraySize(numInstances);
328 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
330 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName, description);
331 parentGroup->addChild(group);
333 baseSeed += (deUint32)testCtx.getCommandLine().getBaseSeed();
335 for (int ndx = 0; ndx < numCases; ndx++)
336 group->addChild(new RandomUniformBlockCase(testCtx, de::toString(ndx), "", bufferMode, features, (deUint32)ndx + baseSeed));
341 class UniformBlockTests : public tcu::TestCaseGroup
344 UniformBlockTests (tcu::TestContext& testCtx);
345 ~UniformBlockTests (void);
350 UniformBlockTests (const UniformBlockTests& other);
351 UniformBlockTests& operator= (const UniformBlockTests& other);
354 UniformBlockTests::UniformBlockTests (tcu::TestContext& testCtx)
355 : TestCaseGroup(testCtx, "ubo", "Uniform Block tests")
359 UniformBlockTests::~UniformBlockTests (void)
363 void UniformBlockTests::init (void)
365 static const glu::DataType basicTypes[] =
368 glu::TYPE_FLOAT_VEC2,
369 glu::TYPE_FLOAT_VEC3,
370 glu::TYPE_FLOAT_VEC4,
383 glu::TYPE_FLOAT_MAT2,
384 glu::TYPE_FLOAT_MAT3,
385 glu::TYPE_FLOAT_MAT4,
386 glu::TYPE_FLOAT_MAT2X3,
387 glu::TYPE_FLOAT_MAT2X4,
388 glu::TYPE_FLOAT_MAT3X2,
389 glu::TYPE_FLOAT_MAT3X4,
390 glu::TYPE_FLOAT_MAT4X2,
391 glu::TYPE_FLOAT_MAT4X3
396 const std::string name;
400 // TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision?
401 { "lowp", PRECISION_LOW },
402 { "mediump", PRECISION_MEDIUM },
403 { "highp", PRECISION_HIGH }
412 { "std140", LAYOUT_STD140 }
417 const std::string name;
421 { "row_major", LAYOUT_ROW_MAJOR },
422 { "column_major", LAYOUT_COLUMN_MAJOR }
428 UniformBlockCase::BufferMode mode;
431 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
432 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE }
437 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level basic array variable in single buffer");
438 addChild(nestedArrayGroup);
440 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
442 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
444 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
446 const glu::DataType type = basicTypes[basicTypeNdx];
447 const char* const typeName = glu::getDataTypeName(type);
448 const int childSize = 4;
449 const int parentSize = 3;
450 const VarType childType (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize);
451 const VarType parentType (childType, parentSize);
453 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
455 if (glu::isDataTypeMatrix(type))
457 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
458 createBlockBasicTypeCases(*layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
459 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
462 nestedArrayGroup->addChild(layoutGroup.release());
468 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
469 addChild(nestedArrayGroup);
471 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
473 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
475 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
477 const glu::DataType type = basicTypes[basicTypeNdx];
478 const char* const typeName = glu::getDataTypeName(type);
479 const int childSize0 = 2;
480 const int childSize1 = 4;
481 const int parentSize = 3;
482 const VarType childType0 (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize0);
483 const VarType childType1 (childType0, childSize1);
484 const VarType parentType (childType1, parentSize);
486 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
488 if (glu::isDataTypeMatrix(type))
490 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
491 createBlockBasicTypeCases(*layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
492 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
495 nestedArrayGroup->addChild(layoutGroup.release());
499 // ubo.2_level_struct_array
501 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one uniform block");
502 addChild(structArrayArrayGroup);
504 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
506 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
507 structArrayArrayGroup->addChild(modeGroup);
509 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
511 for (int isArray = 0; isArray < 2; isArray++)
513 std::string baseName = layoutFlags[layoutFlagNdx].name;
514 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
516 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
517 continue; // Doesn't make sense to add this variant.
520 baseName += "_instance_array";
522 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex"), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
523 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment"), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
524 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both"), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
525 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex_comp_access"), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
526 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment_comp_access"), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
527 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both_comp_access"), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
533 // ubo.single_basic_type
535 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
536 addChild(singleBasicTypeGroup);
538 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
540 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
542 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
544 glu::DataType type = basicTypes[basicTypeNdx];
545 const char* const typeName = glu::getDataTypeName(type);
547 if (glu::isDataTypeBoolOrBVec(type))
548 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
551 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
553 de::MovePtr<tcu::TestCaseGroup> precGroup(new tcu::TestCaseGroup(m_testCtx, precisionFlags[precNdx].name.c_str(), ""));
555 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
557 glu::DataType type = basicTypes[basicTypeNdx];
558 const char* const typeName = glu::getDataTypeName(type);
560 if (!glu::isDataTypeBoolOrBVec(type))
561 createBlockBasicTypeCases(*precGroup, m_testCtx, typeName,
562 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
564 if (glu::isDataTypeMatrix(type))
566 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
568 createBlockBasicTypeCases(*precGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
569 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags);
574 layoutGroup->addChild(precGroup.release());
576 singleBasicTypeGroup->addChild(layoutGroup.release());
580 // ubo.single_basic_array
582 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
583 addChild(singleBasicArrayGroup);
585 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
587 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
589 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
591 glu::DataType type = basicTypes[basicTypeNdx];
592 const char* const typeName = glu::getDataTypeName(type);
593 const int arraySize = 3;
595 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName,
596 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
597 layoutFlags[layoutFlagNdx].flags);
599 if (glu::isDataTypeMatrix(type))
601 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
602 createBlockBasicTypeCases(*layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
603 VarType(VarType(type, PRECISION_HIGH), arraySize),
604 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
607 singleBasicArrayGroup->addChild(layoutGroup.release());
613 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
614 addChild(singleStructGroup);
616 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
618 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
619 singleStructGroup->addChild(modeGroup);
621 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
623 for (int isArray = 0; isArray < 2; isArray++)
625 std::string baseName = layoutFlags[layoutFlagNdx].name;
626 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
628 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
629 continue; // Doesn't make sense to add this variant.
632 baseName += "_instance_array";
634 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
635 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
636 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
637 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
638 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
639 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
645 // ubo.single_struct_array
647 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
648 addChild(singleStructArrayGroup);
650 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
652 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
653 singleStructArrayGroup->addChild(modeGroup);
655 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
657 for (int isArray = 0; isArray < 2; isArray++)
659 std::string baseName = layoutFlags[layoutFlagNdx].name;
660 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
662 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
663 continue; // Doesn't make sense to add this variant.
666 baseName += "_instance_array";
668 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
669 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
670 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
671 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
672 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
673 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
679 // ubo.single_nested_struct
681 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
682 addChild(singleNestedStructGroup);
684 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
686 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
687 singleNestedStructGroup->addChild(modeGroup);
689 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
691 for (int isArray = 0; isArray < 2; isArray++)
693 std::string baseName = layoutFlags[layoutFlagNdx].name;
694 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
696 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
697 continue; // Doesn't make sense to add this variant.
700 baseName += "_instance_array";
702 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
703 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
704 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
705 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
706 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
707 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
713 // ubo.single_nested_struct_array
715 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
716 addChild(singleNestedStructArrayGroup);
718 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
720 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
721 singleNestedStructArrayGroup->addChild(modeGroup);
723 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
725 for (int isArray = 0; isArray < 2; isArray++)
727 std::string baseName = layoutFlags[layoutFlagNdx].name;
728 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
730 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
731 continue; // Doesn't make sense to add this variant.
734 baseName += "_instance_array";
736 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
737 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
738 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
739 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
740 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
741 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
747 // ubo.instance_array_basic_type
749 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
750 addChild(instanceArrayBasicTypeGroup);
752 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
754 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
756 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
758 glu::DataType type = basicTypes[basicTypeNdx];
759 const char* const typeName = glu::getDataTypeName(type);
760 const int numInstances = 3;
762 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName,
763 VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
764 layoutFlags[layoutFlagNdx].flags, numInstances);
766 if (glu::isDataTypeMatrix(type))
768 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
769 createBlockBasicTypeCases(*layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
770 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags,
774 instanceArrayBasicTypeGroup->addChild(layoutGroup.release());
778 // ubo.multi_basic_types
780 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
781 addChild(multiBasicTypesGroup);
783 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
785 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
786 multiBasicTypesGroup->addChild(modeGroup);
788 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
790 for (int isArray = 0; isArray < 2; isArray++)
792 std::string baseName = layoutFlags[layoutFlagNdx].name;
793 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
796 baseName += "_instance_array";
798 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
799 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
800 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));
801 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
802 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));
803 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));
804 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));
805 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));
811 // ubo.multi_nested_struct
813 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
814 addChild(multiNestedStructGroup);
816 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
818 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
819 multiNestedStructGroup->addChild(modeGroup);
821 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
823 for (int isArray = 0; isArray < 2; isArray++)
825 std::string baseName = layoutFlags[layoutFlagNdx].name;
826 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
829 baseName += "_instance_array";
831 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
832 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
833 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));
834 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
835 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));
836 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));
837 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));
838 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));
846 tcu::TestCaseGroup* linkByBindingGroup = new tcu::TestCaseGroup(m_testCtx, "link_by_binding", "Blocks with same name but different binding");
847 addChild(linkByBindingGroup);
849 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_single_instance", "", UniformBlockCase::BUFFERMODE_SINGLE, 0));
850 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_instance_array", "", UniformBlockCase::BUFFERMODE_SINGLE, 2));
851 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_single_instance", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 0));
852 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_instance_array", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 2));
857 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
858 const deUint32 allLayouts = FEATURE_STD140_LAYOUT;
859 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES;
860 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
861 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT;
862 const deUint32 allFeatures = ~FEATURE_OUT_OF_ORDER_OFFSETS; // OOO offsets handled in a dedicated case group
864 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
865 addChild(randomGroup);
868 createRandomCaseGroup(randomGroup, m_testCtx, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused, 25, 0);
869 createRandomCaseGroup(randomGroup, m_testCtx, "vector_types", "Scalar and vector types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|FEATURE_VECTORS, 25, 25);
870 createRandomCaseGroup(randomGroup, m_testCtx, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50);
871 createRandomCaseGroup(randomGroup, m_testCtx, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50);
873 createRandomCaseGroup(randomGroup, m_testCtx, "basic_instance_arrays", "Basic instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_INSTANCE_ARRAYS, 25, 75);
874 createRandomCaseGroup(randomGroup, m_testCtx, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100);
875 createRandomCaseGroup(randomGroup, m_testCtx, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS, 25, 150);
876 createRandomCaseGroup(randomGroup, m_testCtx, "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);
877 createRandomCaseGroup(randomGroup, m_testCtx, "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);
879 createRandomCaseGroup(randomGroup, m_testCtx, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 200);
880 createRandomCaseGroup(randomGroup, m_testCtx, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 250);
882 createRandomCaseGroup(randomGroup, m_testCtx, "all_out_of_order_offsets", "All random features, out of order member offsets", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS, 50, 300);
888 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
890 return new UniformBlockTests(testCtx);