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)
46 : UniformBlockCase(testCtx, name, description, BUFFERMODE_PER_BLOCK)
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 static void createBlockBasicTypeCases (tcu::TestCaseGroup* group, tcu::TestContext& testCtx, const std::string& name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
64 group->addChild(new BlockBasicTypeCase(testCtx, name + "_vertex", "", type, layoutFlags|DECLARE_VERTEX, numInstances));
65 group->addChild(new BlockBasicTypeCase(testCtx, name + "_fragment", "", type, layoutFlags|DECLARE_FRAGMENT, numInstances));
66 group->addChild(new BlockBasicTypeCase(testCtx, name + "_both", "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances));
69 class BlockSingleStructCase : public UniformBlockCase
72 BlockSingleStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
73 : UniformBlockCase (testCtx, name, description, bufferMode)
75 StructType& typeS = m_interface.allocStruct("S");
76 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
77 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
78 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
80 UniformBlock& block = m_interface.allocBlock("Block");
81 block.addUniform(Uniform("s", VarType(&typeS), 0));
82 block.setFlags(layoutFlags);
86 block.setInstanceName("block");
87 block.setArraySize(numInstances);
94 class BlockSingleStructArrayCase : public UniformBlockCase
97 BlockSingleStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
98 : UniformBlockCase (testCtx, name, description, bufferMode)
100 StructType& typeS = m_interface.allocStruct("S");
101 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
102 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
103 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
105 UniformBlock& block = m_interface.allocBlock("Block");
106 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
107 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
108 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
109 block.setFlags(layoutFlags);
111 if (numInstances > 0)
113 block.setInstanceName("block");
114 block.setArraySize(numInstances);
121 class BlockSingleNestedStructCase : public UniformBlockCase
124 BlockSingleNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
125 : UniformBlockCase (testCtx, name, description, bufferMode)
127 StructType& typeS = m_interface.allocStruct("S");
128 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
129 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
130 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
132 StructType& typeT = m_interface.allocStruct("T");
133 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
134 typeT.addMember("b", VarType(&typeS));
136 UniformBlock& block = m_interface.allocBlock("Block");
137 block.addUniform(Uniform("s", VarType(&typeS), 0));
138 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
139 block.addUniform(Uniform("t", VarType(&typeT), 0));
140 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
141 block.setFlags(layoutFlags);
143 if (numInstances > 0)
145 block.setInstanceName("block");
146 block.setArraySize(numInstances);
153 class BlockSingleNestedStructArrayCase : public UniformBlockCase
156 BlockSingleNestedStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
157 : UniformBlockCase (testCtx, name, description, bufferMode)
159 StructType& typeS = m_interface.allocStruct("S");
160 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
161 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
162 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
164 StructType& typeT = m_interface.allocStruct("T");
165 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
166 typeT.addMember("b", VarType(VarType(&typeS), 3));
168 UniformBlock& block = m_interface.allocBlock("Block");
169 block.addUniform(Uniform("s", VarType(&typeS), 0));
170 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
171 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
172 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
173 block.setFlags(layoutFlags);
175 if (numInstances > 0)
177 block.setInstanceName("block");
178 block.setArraySize(numInstances);
185 class BlockMultiBasicTypesCase : public UniformBlockCase
188 BlockMultiBasicTypesCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
189 : UniformBlockCase (testCtx, name, description, bufferMode)
191 UniformBlock& blockA = m_interface.allocBlock("BlockA");
192 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
193 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
194 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
195 blockA.setInstanceName("blockA");
196 blockA.setFlags(flagsA);
198 UniformBlock& blockB = m_interface.allocBlock("BlockB");
199 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
200 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
201 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
202 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
203 blockB.setInstanceName("blockB");
204 blockB.setFlags(flagsB);
206 if (numInstances > 0)
208 blockA.setArraySize(numInstances);
209 blockB.setArraySize(numInstances);
216 class BlockMultiNestedStructCase : public UniformBlockCase
219 BlockMultiNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
220 : UniformBlockCase (testCtx, name, description, bufferMode)
222 StructType& typeS = m_interface.allocStruct("S");
223 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
224 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
225 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
227 StructType& typeT = m_interface.allocStruct("T");
228 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
229 typeT.addMember("b", VarType(&typeS));
230 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
232 UniformBlock& blockA = m_interface.allocBlock("BlockA");
233 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
234 blockA.addUniform(Uniform("b", VarType(&typeS)));
235 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
236 blockA.setInstanceName("blockA");
237 blockA.setFlags(flagsA);
239 UniformBlock& blockB = m_interface.allocBlock("BlockB");
240 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
241 blockB.addUniform(Uniform("b", VarType(&typeT)));
242 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
243 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
244 blockB.setInstanceName("blockB");
245 blockB.setFlags(flagsB);
247 if (numInstances > 0)
249 blockA.setArraySize(numInstances);
250 blockB.setArraySize(numInstances);
257 class Block2LevelStructArrayCase : public UniformBlockCase
260 Block2LevelStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
261 : UniformBlockCase (testCtx, name, description, bufferMode)
262 , m_layoutFlags (layoutFlags)
263 , m_numInstances (numInstances)
265 StructType& typeS = m_interface.allocStruct("S");
266 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
267 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 4));
268 typeS.addMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW));
270 UniformBlock& block = m_interface.allocBlock("Block");
271 block.addUniform(Uniform("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM)));
272 block.addUniform(Uniform("s", VarType(VarType(VarType(&typeS), 3), 2)));
273 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM)));
274 block.setFlags(m_layoutFlags);
276 if (m_numInstances > 0)
278 block.setInstanceName("block");
279 block.setArraySize(m_numInstances);
286 deUint32 m_layoutFlags;
290 class LinkByBindingCase : public UniformBlockCase
293 LinkByBindingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, int numInstances)
294 : UniformBlockCase (testCtx, name, description, bufferMode)
296 UniformBlock& blockA = m_interface.allocBlock("TestBlock");
297 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
298 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
299 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
300 blockA.setFlags(LAYOUT_STD140|DECLARE_VERTEX);
302 UniformBlock& blockB = m_interface.allocBlock("TestBlock");
303 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
304 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
305 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
306 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
307 blockB.setFlags(LAYOUT_STD140|DECLARE_FRAGMENT);
309 if (numInstances > 0)
311 blockA.setInstanceName("testBlock");
312 blockA.setArraySize(numInstances);
313 blockB.setInstanceName("testBlock");
314 blockB.setArraySize(numInstances);
321 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
323 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName, description);
324 parentGroup->addChild(group);
326 baseSeed += (deUint32)testCtx.getCommandLine().getBaseSeed();
328 for (int ndx = 0; ndx < numCases; ndx++)
329 group->addChild(new RandomUniformBlockCase(testCtx, de::toString(ndx), "", bufferMode, features, (deUint32)ndx + baseSeed));
334 class UniformBlockTests : public tcu::TestCaseGroup
337 UniformBlockTests (tcu::TestContext& testCtx);
338 ~UniformBlockTests (void);
343 UniformBlockTests (const UniformBlockTests& other);
344 UniformBlockTests& operator= (const UniformBlockTests& other);
347 UniformBlockTests::UniformBlockTests (tcu::TestContext& testCtx)
348 : TestCaseGroup(testCtx, "ubo", "Uniform Block tests")
352 UniformBlockTests::~UniformBlockTests (void)
356 void UniformBlockTests::init (void)
358 static const glu::DataType basicTypes[] =
361 glu::TYPE_FLOAT_VEC2,
362 glu::TYPE_FLOAT_VEC3,
363 glu::TYPE_FLOAT_VEC4,
376 glu::TYPE_FLOAT_MAT2,
377 glu::TYPE_FLOAT_MAT3,
378 glu::TYPE_FLOAT_MAT4,
379 glu::TYPE_FLOAT_MAT2X3,
380 glu::TYPE_FLOAT_MAT2X4,
381 glu::TYPE_FLOAT_MAT3X2,
382 glu::TYPE_FLOAT_MAT3X4,
383 glu::TYPE_FLOAT_MAT4X2,
384 glu::TYPE_FLOAT_MAT4X3
389 const std::string name;
393 // TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision?
394 { "lowp", PRECISION_LOW },
395 { "mediump", PRECISION_MEDIUM },
396 { "highp", PRECISION_HIGH }
405 { "std140", LAYOUT_STD140 }
410 const std::string name;
414 { "row_major", LAYOUT_ROW_MAJOR },
415 { "column_major", LAYOUT_COLUMN_MAJOR }
421 UniformBlockCase::BufferMode mode;
424 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
425 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE }
430 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level basic array variable in single buffer");
431 addChild(nestedArrayGroup);
433 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
435 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
436 nestedArrayGroup->addChild(layoutGroup);
438 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
440 const glu::DataType type = basicTypes[basicTypeNdx];
441 const char* typeName = glu::getDataTypeName(type);
442 const int childSize = 4;
443 const int parentSize = 3;
444 const VarType childType (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize);
445 const VarType parentType (childType, parentSize);
447 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
449 if (glu::isDataTypeMatrix(type))
451 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
452 createBlockBasicTypeCases(layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
453 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
461 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
462 addChild(nestedArrayGroup);
464 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
466 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
467 nestedArrayGroup->addChild(layoutGroup);
469 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
471 const glu::DataType type = basicTypes[basicTypeNdx];
472 const char* typeName = glu::getDataTypeName(type);
473 const int childSize0 = 2;
474 const int childSize1 = 4;
475 const int parentSize = 3;
476 const VarType childType0 (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize0);
477 const VarType childType1 (childType0, childSize1);
478 const VarType parentType (childType1, parentSize);
480 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
482 if (glu::isDataTypeMatrix(type))
484 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
485 createBlockBasicTypeCases(layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
486 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
492 // ubo.2_level_struct_array
494 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one uniform block");
495 addChild(structArrayArrayGroup);
497 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
499 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
500 structArrayArrayGroup->addChild(modeGroup);
502 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
504 for (int isArray = 0; isArray < 2; isArray++)
506 std::string baseName = layoutFlags[layoutFlagNdx].name;
507 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
509 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
510 continue; // Doesn't make sense to add this variant.
513 baseName += "_instance_array";
515 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex"), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
516 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment"), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
517 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both"), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
523 // ubo.single_basic_type
525 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
526 addChild(singleBasicTypeGroup);
528 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
530 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
531 singleBasicTypeGroup->addChild(layoutGroup);
533 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
535 glu::DataType type = basicTypes[basicTypeNdx];
536 const char* typeName = glu::getDataTypeName(type);
538 if (glu::isDataTypeBoolOrBVec(type))
539 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
542 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
543 createBlockBasicTypeCases(layoutGroup, m_testCtx, precisionFlags[precNdx].name + "_" + typeName,
544 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
547 if (glu::isDataTypeMatrix(type))
549 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
551 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
552 createBlockBasicTypeCases(layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + precisionFlags[precNdx].name + "_" + typeName,
553 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
560 // ubo.single_basic_array
562 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
563 addChild(singleBasicArrayGroup);
565 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
567 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
568 singleBasicArrayGroup->addChild(layoutGroup);
570 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
572 glu::DataType type = basicTypes[basicTypeNdx];
573 const char* typeName = glu::getDataTypeName(type);
574 const int arraySize = 3;
576 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName,
577 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
578 layoutFlags[layoutFlagNdx].flags);
580 if (glu::isDataTypeMatrix(type))
582 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
583 createBlockBasicTypeCases(layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
584 VarType(VarType(type, PRECISION_HIGH), arraySize),
585 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
593 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
594 addChild(singleStructGroup);
596 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
598 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
599 singleStructGroup->addChild(modeGroup);
601 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
603 for (int isArray = 0; isArray < 2; isArray++)
605 std::string baseName = layoutFlags[layoutFlagNdx].name;
606 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
608 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
609 continue; // Doesn't make sense to add this variant.
612 baseName += "_instance_array";
614 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
615 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
616 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
622 // ubo.single_struct_array
624 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
625 addChild(singleStructArrayGroup);
627 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
629 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
630 singleStructArrayGroup->addChild(modeGroup);
632 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
634 for (int isArray = 0; isArray < 2; isArray++)
636 std::string baseName = layoutFlags[layoutFlagNdx].name;
637 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
639 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
640 continue; // Doesn't make sense to add this variant.
643 baseName += "_instance_array";
645 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
646 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
647 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
653 // ubo.single_nested_struct
655 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
656 addChild(singleNestedStructGroup);
658 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
660 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
661 singleNestedStructGroup->addChild(modeGroup);
663 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
665 for (int isArray = 0; isArray < 2; isArray++)
667 std::string baseName = layoutFlags[layoutFlagNdx].name;
668 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
670 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
671 continue; // Doesn't make sense to add this variant.
674 baseName += "_instance_array";
676 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
677 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
678 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
684 // ubo.single_nested_struct_array
686 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
687 addChild(singleNestedStructArrayGroup);
689 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
691 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
692 singleNestedStructArrayGroup->addChild(modeGroup);
694 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
696 for (int isArray = 0; isArray < 2; isArray++)
698 std::string baseName = layoutFlags[layoutFlagNdx].name;
699 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
701 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
702 continue; // Doesn't make sense to add this variant.
705 baseName += "_instance_array";
707 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
708 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
709 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
715 // ubo.instance_array_basic_type
717 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
718 addChild(instanceArrayBasicTypeGroup);
720 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
722 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
723 instanceArrayBasicTypeGroup->addChild(layoutGroup);
725 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
727 glu::DataType type = basicTypes[basicTypeNdx];
728 const char* typeName = glu::getDataTypeName(type);
729 const int numInstances = 3;
731 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName,
732 VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
733 layoutFlags[layoutFlagNdx].flags, numInstances);
735 if (glu::isDataTypeMatrix(type))
737 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
738 createBlockBasicTypeCases(layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
739 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags,
746 // ubo.multi_basic_types
748 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
749 addChild(multiBasicTypesGroup);
751 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
753 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
754 multiBasicTypesGroup->addChild(modeGroup);
756 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
758 for (int isArray = 0; isArray < 2; isArray++)
760 std::string baseName = layoutFlags[layoutFlagNdx].name;
761 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
764 baseName += "_instance_array";
766 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
767 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
768 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
769 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
775 // ubo.multi_nested_struct
777 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
778 addChild(multiNestedStructGroup);
780 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
782 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
783 multiNestedStructGroup->addChild(modeGroup);
785 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
787 for (int isArray = 0; isArray < 2; isArray++)
789 std::string baseName = layoutFlags[layoutFlagNdx].name;
790 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
793 baseName += "_instance_array";
795 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
796 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
797 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
798 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
806 tcu::TestCaseGroup* linkByBindingGroup = new tcu::TestCaseGroup(m_testCtx, "link_by_binding", "Blocks with same name but different binding");
807 addChild(linkByBindingGroup);
809 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_single_instance", "", UniformBlockCase::BUFFERMODE_SINGLE, 0));
810 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_instance_array", "", UniformBlockCase::BUFFERMODE_SINGLE, 2));
811 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_single_instance", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 0));
812 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_instance_array", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 2));
817 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
818 const deUint32 allLayouts = FEATURE_STD140_LAYOUT;
819 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES;
820 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
821 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT;
822 const deUint32 allFeatures = ~FEATURE_ARRAYS_OF_ARRAYS;
824 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
825 addChild(randomGroup);
828 createRandomCaseGroup(randomGroup, m_testCtx, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused, 25, 0);
829 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);
830 createRandomCaseGroup(randomGroup, m_testCtx, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50);
831 createRandomCaseGroup(randomGroup, m_testCtx, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50);
833 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);
834 createRandomCaseGroup(randomGroup, m_testCtx, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100);
835 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);
836 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);
837 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);
839 createRandomCaseGroup(randomGroup, m_testCtx, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 200);
840 createRandomCaseGroup(randomGroup, m_testCtx, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 250);
846 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
848 return new UniformBlockTests(testCtx);