1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Uniform block tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es3fUniformBlockTests.hpp"
25 #include "glsUniformBlockCase.hpp"
26 #include "glsRandomUniformBlockCase.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "deRandom.hpp"
29 #include "deStringUtil.hpp"
41 using gls::UniformBlockCase;
42 using gls::RandomUniformBlockCase;
43 using namespace gls::ub;
45 static void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, Context& context, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
47 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
48 parentGroup->addChild(group);
50 baseSeed += (deUint32)context.getTestContext().getCommandLine().getBaseSeed();
52 for (int ndx = 0; ndx < numCases; ndx++)
53 group->addChild(new RandomUniformBlockCase(context.getTestContext(), context.getRenderContext(), glu::GLSL_VERSION_300_ES,
54 de::toString(ndx).c_str(), "", bufferMode, features, (deUint32)ndx+baseSeed));
57 class BlockBasicTypeCase : public UniformBlockCase
60 BlockBasicTypeCase (Context& context, const char* name, const char* description, const VarType& type, deUint32 layoutFlags, int numInstances)
61 : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, BUFFERMODE_PER_BLOCK)
63 UniformBlock& block = m_interface.allocBlock("Block");
64 block.addUniform(Uniform("var", type, 0));
65 block.setFlags(layoutFlags);
69 block.setArraySize(numInstances);
70 block.setInstanceName("block");
75 static void createBlockBasicTypeCases (tcu::TestCaseGroup* group, Context& context, const char* name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
77 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_vertex").c_str(), "", type, layoutFlags|DECLARE_VERTEX, numInstances));
78 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_fragment").c_str(), "", type, layoutFlags|DECLARE_FRAGMENT, numInstances));
80 if (!(layoutFlags & LAYOUT_PACKED))
81 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_both").c_str(), "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances));
84 class BlockSingleStructCase : public UniformBlockCase
87 BlockSingleStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
88 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
89 , m_layoutFlags (layoutFlags)
90 , m_numInstances (numInstances)
96 StructType& typeS = m_interface.allocStruct("S");
97 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
98 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
99 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
101 UniformBlock& block = m_interface.allocBlock("Block");
102 block.addUniform(Uniform("s", VarType(&typeS), 0));
103 block.setFlags(m_layoutFlags);
105 if (m_numInstances > 0)
107 block.setInstanceName("block");
108 block.setArraySize(m_numInstances);
113 deUint32 m_layoutFlags;
117 class BlockSingleStructArrayCase : public UniformBlockCase
120 BlockSingleStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
121 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
122 , m_layoutFlags (layoutFlags)
123 , m_numInstances (numInstances)
129 StructType& typeS = m_interface.allocStruct("S");
130 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
131 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
132 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
134 UniformBlock& block = m_interface.allocBlock("Block");
135 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
136 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
137 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
138 block.setFlags(m_layoutFlags);
140 if (m_numInstances > 0)
142 block.setInstanceName("block");
143 block.setArraySize(m_numInstances);
148 deUint32 m_layoutFlags;
152 class BlockSingleNestedStructCase : public UniformBlockCase
155 BlockSingleNestedStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
156 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
157 , m_layoutFlags (layoutFlags)
158 , m_numInstances (numInstances)
164 StructType& typeS = m_interface.allocStruct("S");
165 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
166 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
167 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
169 StructType& typeT = m_interface.allocStruct("T");
170 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
171 typeT.addMember("b", VarType(&typeS));
173 UniformBlock& block = m_interface.allocBlock("Block");
174 block.addUniform(Uniform("s", VarType(&typeS), 0));
175 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
176 block.addUniform(Uniform("t", VarType(&typeT), 0));
177 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
178 block.setFlags(m_layoutFlags);
180 if (m_numInstances > 0)
182 block.setInstanceName("block");
183 block.setArraySize(m_numInstances);
188 deUint32 m_layoutFlags;
192 class BlockSingleNestedStructArrayCase : public UniformBlockCase
195 BlockSingleNestedStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
196 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
197 , m_layoutFlags (layoutFlags)
198 , m_numInstances (numInstances)
204 StructType& typeS = m_interface.allocStruct("S");
205 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
206 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
207 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
209 StructType& typeT = m_interface.allocStruct("T");
210 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
211 typeT.addMember("b", VarType(VarType(&typeS), 3));
213 UniformBlock& block = m_interface.allocBlock("Block");
214 block.addUniform(Uniform("s", VarType(&typeS), 0));
215 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
216 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
217 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
218 block.setFlags(m_layoutFlags);
220 if (m_numInstances > 0)
222 block.setInstanceName("block");
223 block.setArraySize(m_numInstances);
228 deUint32 m_layoutFlags;
232 class BlockMultiBasicTypesCase : public UniformBlockCase
235 BlockMultiBasicTypesCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
236 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
239 , m_numInstances (numInstances)
245 UniformBlock& blockA = m_interface.allocBlock("BlockA");
246 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
247 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
248 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
249 blockA.setInstanceName("blockA");
250 blockA.setFlags(m_flagsA);
252 UniformBlock& blockB = m_interface.allocBlock("BlockB");
253 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
254 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
255 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
256 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
257 blockB.setInstanceName("blockB");
258 blockB.setFlags(m_flagsB);
260 if (m_numInstances > 0)
262 blockA.setArraySize(m_numInstances);
263 blockB.setArraySize(m_numInstances);
273 class BlockMultiNestedStructCase : public UniformBlockCase
276 BlockMultiNestedStructCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
277 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
280 , m_numInstances (numInstances)
286 StructType& typeS = m_interface.allocStruct("S");
287 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
288 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
289 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
291 StructType& typeT = m_interface.allocStruct("T");
292 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
293 typeT.addMember("b", VarType(&typeS));
294 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
296 UniformBlock& blockA = m_interface.allocBlock("BlockA");
297 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
298 blockA.addUniform(Uniform("b", VarType(&typeS)));
299 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
300 blockA.setInstanceName("blockA");
301 blockA.setFlags(m_flagsA);
303 UniformBlock& blockB = m_interface.allocBlock("BlockB");
304 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
305 blockB.addUniform(Uniform("b", VarType(&typeT)));
306 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
307 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
308 blockB.setInstanceName("blockB");
309 blockB.setFlags(m_flagsB);
311 if (m_numInstances > 0)
313 blockA.setArraySize(m_numInstances);
314 blockB.setArraySize(m_numInstances);
324 UniformBlockTests::UniformBlockTests (Context& context)
325 : TestCaseGroup(context, "ubo", "Uniform Block tests")
329 UniformBlockTests::~UniformBlockTests (void)
333 void UniformBlockTests::init (void)
335 static const glu::DataType basicTypes[] =
338 glu::TYPE_FLOAT_VEC2,
339 glu::TYPE_FLOAT_VEC3,
340 glu::TYPE_FLOAT_VEC4,
353 glu::TYPE_FLOAT_MAT2,
354 glu::TYPE_FLOAT_MAT3,
355 glu::TYPE_FLOAT_MAT4,
356 glu::TYPE_FLOAT_MAT2X3,
357 glu::TYPE_FLOAT_MAT2X4,
358 glu::TYPE_FLOAT_MAT3X2,
359 glu::TYPE_FLOAT_MAT3X4,
360 glu::TYPE_FLOAT_MAT4X2,
361 glu::TYPE_FLOAT_MAT4X3
370 { "lowp", PRECISION_LOW },
371 { "mediump", PRECISION_MEDIUM },
372 { "highp", PRECISION_HIGH }
381 { "shared", LAYOUT_SHARED },
382 { "packed", LAYOUT_PACKED },
383 { "std140", LAYOUT_STD140 }
392 { "row_major", LAYOUT_ROW_MAJOR },
393 { "column_major", LAYOUT_COLUMN_MAJOR }
399 UniformBlockCase::BufferMode mode;
402 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
403 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE }
406 // ubo.single_basic_type
408 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
409 addChild(singleBasicTypeGroup);
411 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
413 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
414 singleBasicTypeGroup->addChild(layoutGroup);
416 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
418 glu::DataType type = basicTypes[basicTypeNdx];
419 const char* typeName = glu::getDataTypeName(type);
421 if (glu::isDataTypeBoolOrBVec(type))
422 createBlockBasicTypeCases(layoutGroup, m_context, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
425 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
426 createBlockBasicTypeCases(layoutGroup, m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(),
427 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
430 if (glu::isDataTypeMatrix(type))
432 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
434 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
435 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + precisionFlags[precNdx].name + "_" + typeName).c_str(),
436 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
443 // ubo.single_basic_array
445 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
446 addChild(singleBasicArrayGroup);
448 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
450 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
451 singleBasicArrayGroup->addChild(layoutGroup);
453 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
455 glu::DataType type = basicTypes[basicTypeNdx];
456 const char* typeName = glu::getDataTypeName(type);
457 const int arraySize = 3;
459 createBlockBasicTypeCases(layoutGroup, m_context, typeName,
460 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
461 layoutFlags[layoutFlagNdx].flags);
463 if (glu::isDataTypeMatrix(type))
465 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
466 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
467 VarType(VarType(type, PRECISION_HIGH), arraySize),
468 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
476 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
477 addChild(singleStructGroup);
479 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
481 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
482 singleStructGroup->addChild(modeGroup);
484 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
486 for (int isArray = 0; isArray < 2; isArray++)
488 std::string baseName = layoutFlags[layoutFlagNdx].name;
489 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
491 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
492 continue; // Doesn't make sense to add this variant.
495 baseName += "_instance_array";
497 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
498 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
500 if (!(baseFlags & LAYOUT_PACKED))
501 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
507 // ubo.single_struct_array
509 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
510 addChild(singleStructArrayGroup);
512 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
514 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
515 singleStructArrayGroup->addChild(modeGroup);
517 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
519 for (int isArray = 0; isArray < 2; isArray++)
521 std::string baseName = layoutFlags[layoutFlagNdx].name;
522 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
524 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
525 continue; // Doesn't make sense to add this variant.
528 baseName += "_instance_array";
530 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
531 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
533 if (!(baseFlags & LAYOUT_PACKED))
534 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
540 // ubo.single_nested_struct
542 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
543 addChild(singleNestedStructGroup);
545 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
547 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
548 singleNestedStructGroup->addChild(modeGroup);
550 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
552 for (int isArray = 0; isArray < 2; isArray++)
554 std::string baseName = layoutFlags[layoutFlagNdx].name;
555 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
557 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
558 continue; // Doesn't make sense to add this variant.
561 baseName += "_instance_array";
563 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
564 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
566 if (!(baseFlags & LAYOUT_PACKED))
567 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
573 // ubo.single_nested_struct_array
575 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
576 addChild(singleNestedStructArrayGroup);
578 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
580 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
581 singleNestedStructArrayGroup->addChild(modeGroup);
583 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
585 for (int isArray = 0; isArray < 2; isArray++)
587 std::string baseName = layoutFlags[layoutFlagNdx].name;
588 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
590 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
591 continue; // Doesn't make sense to add this variant.
594 baseName += "_instance_array";
596 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
597 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
599 if (!(baseFlags & LAYOUT_PACKED))
600 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
606 // ubo.instance_array_basic_type
608 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
609 addChild(instanceArrayBasicTypeGroup);
611 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
613 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
614 instanceArrayBasicTypeGroup->addChild(layoutGroup);
616 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
618 glu::DataType type = basicTypes[basicTypeNdx];
619 const char* typeName = glu::getDataTypeName(type);
620 const int numInstances = 3;
622 createBlockBasicTypeCases(layoutGroup, m_context, typeName,
623 VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
624 layoutFlags[layoutFlagNdx].flags, numInstances);
626 if (glu::isDataTypeMatrix(type))
628 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
629 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
630 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags,
637 // ubo.multi_basic_types
639 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
640 addChild(multiBasicTypesGroup);
642 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
644 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
645 multiBasicTypesGroup->addChild(modeGroup);
647 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
649 for (int isArray = 0; isArray < 2; isArray++)
651 std::string baseName = layoutFlags[layoutFlagNdx].name;
652 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
655 baseName += "_instance_array";
657 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
658 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
660 if (!(baseFlags & LAYOUT_PACKED))
661 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
663 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
669 // ubo.multi_nested_struct
671 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
672 addChild(multiNestedStructGroup);
674 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
676 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
677 multiNestedStructGroup->addChild(modeGroup);
679 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
681 for (int isArray = 0; isArray < 2; isArray++)
683 std::string baseName = layoutFlags[layoutFlagNdx].name;
684 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
687 baseName += "_instance_array";
689 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
690 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
692 if (!(baseFlags & LAYOUT_PACKED))
693 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
695 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
703 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
704 const deUint32 allLayouts = FEATURE_PACKED_LAYOUT|FEATURE_SHARED_LAYOUT|FEATURE_STD140_LAYOUT;
705 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES;
706 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
707 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT;
708 const deUint32 allFeatures = ~FEATURE_ARRAYS_OF_ARRAYS;
710 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
711 addChild(randomGroup);
714 createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused, 25, 0);
715 createRandomCaseGroup(randomGroup, m_context, "vector_types", "Scalar and vector types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|FEATURE_VECTORS, 25, 25);
716 createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50);
717 createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50);
719 createRandomCaseGroup(randomGroup, m_context, "basic_instance_arrays", "Basic instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_INSTANCE_ARRAYS, 25, 75);
720 createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100);
721 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS, 25, 150);
722 createRandomCaseGroup(randomGroup, m_context, "nested_structs_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS, 25, 125);
723 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS, 25, 175);
725 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 200);
726 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 250);