Merge \\"Add tests for uniform block linking by binding\\" into nyc-dev am: 845104ba90
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / ubo / vktUniformBlockTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Uniform block tests.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktUniformBlockTests.hpp"
27
28 #include "vktUniformBlockCase.hpp"
29 #include "vktRandomUniformBlockCase.hpp"
30
31 #include "tcuCommandLine.hpp"
32 #include "deStringUtil.hpp"
33
34 namespace vkt
35 {
36 namespace ubo
37 {
38
39 namespace
40 {
41
42 class BlockBasicTypeCase : public UniformBlockCase
43 {
44 public:
45         BlockBasicTypeCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const VarType& type, deUint32 layoutFlags, int numInstances)
46                 : UniformBlockCase(testCtx, name, description, BUFFERMODE_PER_BLOCK)
47         {
48                 UniformBlock& block = m_interface.allocBlock("Block");
49                 block.addUniform(Uniform("var", type, 0));
50                 block.setFlags(layoutFlags);
51
52                 if (numInstances > 0)
53                 {
54                         block.setArraySize(numInstances);
55                         block.setInstanceName("block");
56                 }
57
58                 init();
59         }
60 };
61
62 static void createBlockBasicTypeCases (tcu::TestCaseGroup* group, tcu::TestContext& testCtx, const std::string& name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
63 {
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));
67 }
68
69 class BlockSingleStructCase : public UniformBlockCase
70 {
71 public:
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)
74         {
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));
79
80                 UniformBlock& block = m_interface.allocBlock("Block");
81                 block.addUniform(Uniform("s", VarType(&typeS), 0));
82                 block.setFlags(layoutFlags);
83
84                 if (numInstances > 0)
85                 {
86                         block.setInstanceName("block");
87                         block.setArraySize(numInstances);
88                 }
89
90                 init();
91         }
92 };
93
94 class BlockSingleStructArrayCase : public UniformBlockCase
95 {
96 public:
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)
99         {
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));
104
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);
110
111                 if (numInstances > 0)
112                 {
113                         block.setInstanceName("block");
114                         block.setArraySize(numInstances);
115                 }
116
117                 init();
118         }
119 };
120
121 class BlockSingleNestedStructCase : public UniformBlockCase
122 {
123 public:
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)
126         {
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);
131
132                 StructType& typeT = m_interface.allocStruct("T");
133                 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
134                 typeT.addMember("b", VarType(&typeS));
135
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);
142
143                 if (numInstances > 0)
144                 {
145                         block.setInstanceName("block");
146                         block.setArraySize(numInstances);
147                 }
148
149                 init();
150         }
151 };
152
153 class BlockSingleNestedStructArrayCase : public UniformBlockCase
154 {
155 public:
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)
158         {
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);
163
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));
167
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);
174
175                 if (numInstances > 0)
176                 {
177                         block.setInstanceName("block");
178                         block.setArraySize(numInstances);
179                 }
180
181                 init();
182         }
183 };
184
185 class BlockMultiBasicTypesCase : public UniformBlockCase
186 {
187 public:
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)
190         {
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);
197
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);
205
206                 if (numInstances > 0)
207                 {
208                         blockA.setArraySize(numInstances);
209                         blockB.setArraySize(numInstances);
210                 }
211
212                 init();
213         }
214 };
215
216 class BlockMultiNestedStructCase : public UniformBlockCase
217 {
218 public:
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)
221         {
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));
226
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));
231
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);
238
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);
246
247                 if (numInstances > 0)
248                 {
249                         blockA.setArraySize(numInstances);
250                         blockB.setArraySize(numInstances);
251                 }
252
253                 init();
254         }
255 };
256
257 class Block2LevelStructArrayCase : public UniformBlockCase
258 {
259 public:
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)
264         {
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));
269
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);
275
276                 if (m_numInstances > 0)
277                 {
278                         block.setInstanceName("block");
279                         block.setArraySize(m_numInstances);
280                 }
281
282                 init();
283         }
284
285 private:
286         deUint32        m_layoutFlags;
287         int                     m_numInstances;
288 };
289
290 class LinkByBindingCase : public UniformBlockCase
291 {
292 public:
293         LinkByBindingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, int numInstances)
294                 : UniformBlockCase      (testCtx, name, description, bufferMode)
295         {
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);
301
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);
308
309                 if (numInstances > 0)
310                 {
311                         blockA.setInstanceName("testBlock");
312                         blockA.setArraySize(numInstances);
313                         blockB.setInstanceName("testBlock");
314                         blockB.setArraySize(numInstances);
315                 }
316
317                 init();
318         }
319 };
320
321 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
322 {
323         tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName, description);
324         parentGroup->addChild(group);
325
326         baseSeed += (deUint32)testCtx.getCommandLine().getBaseSeed();
327
328         for (int ndx = 0; ndx < numCases; ndx++)
329                 group->addChild(new RandomUniformBlockCase(testCtx, de::toString(ndx), "", bufferMode, features, (deUint32)ndx + baseSeed));
330 }
331
332 // UniformBlockTests
333
334 class UniformBlockTests : public tcu::TestCaseGroup
335 {
336 public:
337                                                         UniformBlockTests               (tcu::TestContext& testCtx);
338                                                         ~UniformBlockTests              (void);
339
340         void                                    init                                    (void);
341
342 private:
343                                                         UniformBlockTests               (const UniformBlockTests& other);
344         UniformBlockTests&              operator=                               (const UniformBlockTests& other);
345 };
346
347 UniformBlockTests::UniformBlockTests (tcu::TestContext& testCtx)
348         : TestCaseGroup(testCtx, "ubo", "Uniform Block tests")
349 {
350 }
351
352 UniformBlockTests::~UniformBlockTests (void)
353 {
354 }
355
356 void UniformBlockTests::init (void)
357 {
358         static const glu::DataType basicTypes[] =
359         {
360                 glu::TYPE_FLOAT,
361                 glu::TYPE_FLOAT_VEC2,
362                 glu::TYPE_FLOAT_VEC3,
363                 glu::TYPE_FLOAT_VEC4,
364                 glu::TYPE_INT,
365                 glu::TYPE_INT_VEC2,
366                 glu::TYPE_INT_VEC3,
367                 glu::TYPE_INT_VEC4,
368                 glu::TYPE_UINT,
369                 glu::TYPE_UINT_VEC2,
370                 glu::TYPE_UINT_VEC3,
371                 glu::TYPE_UINT_VEC4,
372                 glu::TYPE_BOOL,
373                 glu::TYPE_BOOL_VEC2,
374                 glu::TYPE_BOOL_VEC3,
375                 glu::TYPE_BOOL_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
385         };
386
387         static const struct
388         {
389                 const std::string       name;
390                 deUint32                        flags;
391         } precisionFlags[] =
392         {
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          }
397         };
398
399         static const struct
400         {
401                 const char*                     name;
402                 deUint32                        flags;
403         } layoutFlags[] =
404         {
405                 { "std140",             LAYOUT_STD140   }
406         };
407
408         static const struct
409         {
410                 const std::string       name;
411                 deUint32                        flags;
412         } matrixFlags[] =
413         {
414                 { "row_major",          LAYOUT_ROW_MAJOR        },
415                 { "column_major",       LAYOUT_COLUMN_MAJOR }
416         };
417
418         static const struct
419         {
420                 const char*                                                     name;
421                 UniformBlockCase::BufferMode            mode;
422         } bufferModes[] =
423         {
424                 { "per_block_buffer",   UniformBlockCase::BUFFERMODE_PER_BLOCK },
425                 { "single_buffer",              UniformBlockCase::BUFFERMODE_SINGLE     }
426         };
427
428         // ubo.2_level_array
429         {
430                 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level basic array variable in single buffer");
431                 addChild(nestedArrayGroup);
432
433                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
434                 {
435                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
436                         nestedArrayGroup->addChild(layoutGroup);
437
438                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
439                         {
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);
446
447                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
448
449                                 if (glu::isDataTypeMatrix(type))
450                                 {
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);
454                                 }
455                         }
456                 }
457         }
458
459         // ubo.3_level_array
460         {
461                 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
462                 addChild(nestedArrayGroup);
463
464                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
465                 {
466                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
467                         nestedArrayGroup->addChild(layoutGroup);
468
469                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
470                         {
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);
479
480                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
481
482                                 if (glu::isDataTypeMatrix(type))
483                                 {
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);
487                                 }
488                         }
489                 }
490         }
491
492         // ubo.2_level_struct_array
493         {
494                 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one uniform block");
495                 addChild(structArrayArrayGroup);
496
497                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
498                 {
499                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
500                         structArrayArrayGroup->addChild(modeGroup);
501
502                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
503                         {
504                                 for (int isArray = 0; isArray < 2; isArray++)
505                                 {
506                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
507                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
508
509                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
510                                                 continue; // Doesn't make sense to add this variant.
511
512                                         if (isArray)
513                                                 baseName += "_instance_array";
514
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));
518                                 }
519                         }
520                 }
521         }
522
523         // ubo.single_basic_type
524         {
525                 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
526                 addChild(singleBasicTypeGroup);
527
528                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
529                 {
530                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
531                         singleBasicTypeGroup->addChild(layoutGroup);
532
533                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
534                         {
535                                 glu::DataType   type            = basicTypes[basicTypeNdx];
536                                 const char*             typeName        = glu::getDataTypeName(type);
537
538                                 if (glu::isDataTypeBoolOrBVec(type))
539                                         createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
540                                 else
541                                 {
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);
545                                 }
546
547                                 if (glu::isDataTypeMatrix(type))
548                                 {
549                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
550                                         {
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);
554                                         }
555                                 }
556                         }
557                 }
558         }
559
560         // ubo.single_basic_array
561         {
562                 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
563                 addChild(singleBasicArrayGroup);
564
565                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
566                 {
567                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
568                         singleBasicArrayGroup->addChild(layoutGroup);
569
570                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
571                         {
572                                 glu::DataType   type            = basicTypes[basicTypeNdx];
573                                 const char*             typeName        = glu::getDataTypeName(type);
574                                 const int               arraySize       = 3;
575
576                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName,
577                                                                                   VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
578                                                                                   layoutFlags[layoutFlagNdx].flags);
579
580                                 if (glu::isDataTypeMatrix(type))
581                                 {
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);
586                                 }
587                         }
588                 }
589         }
590
591         // ubo.single_struct
592         {
593                 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
594                 addChild(singleStructGroup);
595
596                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
597                 {
598                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
599                         singleStructGroup->addChild(modeGroup);
600
601                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
602                         {
603                                 for (int isArray = 0; isArray < 2; isArray++)
604                                 {
605                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
606                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
607
608                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
609                                                 continue; // Doesn't make sense to add this variant.
610
611                                         if (isArray)
612                                                 baseName += "_instance_array";
613
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));
617                                 }
618                         }
619                 }
620         }
621
622         // ubo.single_struct_array
623         {
624                 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
625                 addChild(singleStructArrayGroup);
626
627                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
628                 {
629                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
630                         singleStructArrayGroup->addChild(modeGroup);
631
632                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
633                         {
634                                 for (int isArray = 0; isArray < 2; isArray++)
635                                 {
636                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
637                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
638
639                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
640                                                 continue; // Doesn't make sense to add this variant.
641
642                                         if (isArray)
643                                                 baseName += "_instance_array";
644
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));
648                                 }
649                         }
650                 }
651         }
652
653         // ubo.single_nested_struct
654         {
655                 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
656                 addChild(singleNestedStructGroup);
657
658                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
659                 {
660                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
661                         singleNestedStructGroup->addChild(modeGroup);
662
663                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
664                         {
665                                 for (int isArray = 0; isArray < 2; isArray++)
666                                 {
667                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
668                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
669
670                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
671                                                 continue; // Doesn't make sense to add this variant.
672
673                                         if (isArray)
674                                                 baseName += "_instance_array";
675
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));
679                                 }
680                         }
681                 }
682         }
683
684         // ubo.single_nested_struct_array
685         {
686                 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
687                 addChild(singleNestedStructArrayGroup);
688
689                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
690                 {
691                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
692                         singleNestedStructArrayGroup->addChild(modeGroup);
693
694                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
695                         {
696                                 for (int isArray = 0; isArray < 2; isArray++)
697                                 {
698                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
699                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
700
701                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
702                                                 continue; // Doesn't make sense to add this variant.
703
704                                         if (isArray)
705                                                 baseName += "_instance_array";
706
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));
710                                 }
711                         }
712                 }
713         }
714
715         // ubo.instance_array_basic_type
716         {
717                 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
718                 addChild(instanceArrayBasicTypeGroup);
719
720                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
721                 {
722                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
723                         instanceArrayBasicTypeGroup->addChild(layoutGroup);
724
725                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
726                         {
727                                 glu::DataType   type                    = basicTypes[basicTypeNdx];
728                                 const char*             typeName                = glu::getDataTypeName(type);
729                                 const int               numInstances    = 3;
730
731                                 createBlockBasicTypeCases(layoutGroup, m_testCtx, typeName,
732                                                                                   VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
733                                                                                   layoutFlags[layoutFlagNdx].flags, numInstances);
734
735                                 if (glu::isDataTypeMatrix(type))
736                                 {
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,
740                                                                                                   numInstances);
741                                 }
742                         }
743                 }
744         }
745
746         // ubo.multi_basic_types
747         {
748                 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
749                 addChild(multiBasicTypesGroup);
750
751                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
752                 {
753                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
754                         multiBasicTypesGroup->addChild(modeGroup);
755
756                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
757                         {
758                                 for (int isArray = 0; isArray < 2; isArray++)
759                                 {
760                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
761                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
762
763                                         if (isArray)
764                                                 baseName += "_instance_array";
765
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));
770                                 }
771                         }
772                 }
773         }
774
775         // ubo.multi_nested_struct
776         {
777                 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
778                 addChild(multiNestedStructGroup);
779
780                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
781                 {
782                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
783                         multiNestedStructGroup->addChild(modeGroup);
784
785                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
786                         {
787                                 for (int isArray = 0; isArray < 2; isArray++)
788                                 {
789                                         std::string     baseName        = layoutFlags[layoutFlagNdx].name;
790                                         deUint32        baseFlags       = layoutFlags[layoutFlagNdx].flags;
791
792                                         if (isArray)
793                                                 baseName += "_instance_array";
794
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));
799                                 }
800                         }
801                 }
802         }
803
804         // .link_by_binding
805         {
806                 tcu::TestCaseGroup* linkByBindingGroup = new tcu::TestCaseGroup(m_testCtx, "link_by_binding", "Blocks with same name but different binding");
807                 addChild(linkByBindingGroup);
808
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));
813         }
814
815         // ubo.random
816         {
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;
823
824                 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
825                 addChild(randomGroup);
826
827                 // Basic types.
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);
832
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);
838
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);
841         }
842 }
843
844 } // anonymous
845
846 tcu::TestCaseGroup*     createTests     (tcu::TestContext& testCtx)
847 {
848         return new UniformBlockTests(testCtx);
849 }
850
851 } // ubo
852 } // vkt