xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fUniformBlockTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *//*!
20  * \file
21  * \brief Uniform block tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fUniformBlockTests.hpp"
25 #include "glsUniformBlockCase.hpp"
26 #include "glsRandomUniformBlockCase.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "deRandom.hpp"
29 #include "deStringUtil.hpp"
30 
31 using std::string;
32 using std::vector;
33 
34 namespace deqp
35 {
36 namespace gles3
37 {
38 namespace Functional
39 {
40 
41 using gls::RandomUniformBlockCase;
42 using gls::UniformBlockCase;
43 using namespace gls::ub;
44 
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,Context & context,const char * groupName,const char * description,UniformBlockCase::BufferMode bufferMode,uint32_t features,int numCases,uint32_t baseSeed)45 static void createRandomCaseGroup(tcu::TestCaseGroup *parentGroup, Context &context, const char *groupName,
46                                   const char *description, UniformBlockCase::BufferMode bufferMode, uint32_t features,
47                                   int numCases, uint32_t baseSeed)
48 {
49     tcu::TestCaseGroup *group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
50     parentGroup->addChild(group);
51 
52     baseSeed += (uint32_t)context.getTestContext().getCommandLine().getBaseSeed();
53 
54     for (int ndx = 0; ndx < numCases; ndx++)
55         group->addChild(new RandomUniformBlockCase(context.getTestContext(), context.getRenderContext(),
56                                                    glu::GLSL_VERSION_300_ES, de::toString(ndx).c_str(), "", bufferMode,
57                                                    features, (uint32_t)ndx + baseSeed));
58 }
59 
60 class BlockBasicTypeCase : public UniformBlockCase
61 {
62 public:
BlockBasicTypeCase(Context & context,const char * name,const char * description,const VarType & type,uint32_t layoutFlags,int numInstances)63     BlockBasicTypeCase(Context &context, const char *name, const char *description, const VarType &type,
64                        uint32_t layoutFlags, int numInstances)
65         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
66                            glu::GLSL_VERSION_300_ES, BUFFERMODE_PER_BLOCK)
67     {
68         UniformBlock &block = m_interface.allocBlock("Block");
69         block.addUniform(Uniform("var", type, 0));
70         block.setFlags(layoutFlags);
71 
72         if (numInstances > 0)
73         {
74             block.setArraySize(numInstances);
75             block.setInstanceName("block");
76         }
77     }
78 };
79 
createBlockBasicTypeCases(tcu::TestCaseGroup * group,Context & context,const char * name,const VarType & type,uint32_t layoutFlags,int numInstances=0)80 static void createBlockBasicTypeCases(tcu::TestCaseGroup *group, Context &context, const char *name,
81                                       const VarType &type, uint32_t layoutFlags, int numInstances = 0)
82 {
83     group->addChild(new BlockBasicTypeCase(context, (string(name) + "_vertex").c_str(), "", type,
84                                            layoutFlags | DECLARE_VERTEX, numInstances));
85     group->addChild(new BlockBasicTypeCase(context, (string(name) + "_fragment").c_str(), "", type,
86                                            layoutFlags | DECLARE_FRAGMENT, numInstances));
87 
88     if (!(layoutFlags & LAYOUT_PACKED))
89         group->addChild(new BlockBasicTypeCase(context, (string(name) + "_both").c_str(), "", type,
90                                                layoutFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, numInstances));
91 }
92 
93 class BlockSingleStructCase : public UniformBlockCase
94 {
95 public:
BlockSingleStructCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)96     BlockSingleStructCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
97                           BufferMode bufferMode, int numInstances)
98         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
99                            glu::GLSL_VERSION_300_ES, bufferMode)
100         , m_layoutFlags(layoutFlags)
101         , m_numInstances(numInstances)
102     {
103     }
104 
init(void)105     void init(void)
106     {
107         StructType &typeS = m_interface.allocStruct("S");
108         typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
109         typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
110         typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
111 
112         UniformBlock &block = m_interface.allocBlock("Block");
113         block.addUniform(Uniform("s", VarType(&typeS), 0));
114         block.setFlags(m_layoutFlags);
115 
116         if (m_numInstances > 0)
117         {
118             block.setInstanceName("block");
119             block.setArraySize(m_numInstances);
120         }
121     }
122 
123 private:
124     uint32_t m_layoutFlags;
125     int m_numInstances;
126 };
127 
128 class BlockSingleStructArrayCase : public UniformBlockCase
129 {
130 public:
BlockSingleStructArrayCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)131     BlockSingleStructArrayCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
132                                BufferMode bufferMode, int numInstances)
133         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
134                            glu::GLSL_VERSION_300_ES, bufferMode)
135         , m_layoutFlags(layoutFlags)
136         , m_numInstances(numInstances)
137     {
138     }
139 
init(void)140     void init(void)
141     {
142         StructType &typeS = m_interface.allocStruct("S");
143         typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
144         typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
145         typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
146 
147         UniformBlock &block = m_interface.allocBlock("Block");
148         block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
149         block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
150         block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
151         block.setFlags(m_layoutFlags);
152 
153         if (m_numInstances > 0)
154         {
155             block.setInstanceName("block");
156             block.setArraySize(m_numInstances);
157         }
158     }
159 
160 private:
161     uint32_t m_layoutFlags;
162     int m_numInstances;
163 };
164 
165 class BlockSingleNestedStructCase : public UniformBlockCase
166 {
167 public:
BlockSingleNestedStructCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)168     BlockSingleNestedStructCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
169                                 BufferMode bufferMode, int numInstances)
170         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
171                            glu::GLSL_VERSION_300_ES, bufferMode)
172         , m_layoutFlags(layoutFlags)
173         , m_numInstances(numInstances)
174     {
175     }
176 
init(void)177     void init(void)
178     {
179         StructType &typeS = m_interface.allocStruct("S");
180         typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
181         typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
182         typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
183 
184         StructType &typeT = m_interface.allocStruct("T");
185         typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
186         typeT.addMember("b", VarType(&typeS));
187 
188         UniformBlock &block = m_interface.allocBlock("Block");
189         block.addUniform(Uniform("s", VarType(&typeS), 0));
190         block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
191         block.addUniform(Uniform("t", VarType(&typeT), 0));
192         block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
193         block.setFlags(m_layoutFlags);
194 
195         if (m_numInstances > 0)
196         {
197             block.setInstanceName("block");
198             block.setArraySize(m_numInstances);
199         }
200     }
201 
202 private:
203     uint32_t m_layoutFlags;
204     int m_numInstances;
205 };
206 
207 class BlockSingleNestedStructMixedMatrixPackingCase : public UniformBlockCase
208 {
209 public:
BlockSingleNestedStructMixedMatrixPackingCase(Context & context,const char * name,const char * description,uint32_t blockLayoutFlags,uint32_t matrixLayoutFlags,uint32_t matrixArrayLayoutFlags,BufferMode bufferMode,int numInstances)210     BlockSingleNestedStructMixedMatrixPackingCase(Context &context, const char *name, const char *description,
211                                                   uint32_t blockLayoutFlags, uint32_t matrixLayoutFlags,
212                                                   uint32_t matrixArrayLayoutFlags, BufferMode bufferMode,
213                                                   int numInstances)
214         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
215                            glu::GLSL_VERSION_300_ES, bufferMode)
216         , m_blockLayoutFlags(blockLayoutFlags)
217         , m_matrixLayoutFlags(matrixLayoutFlags)
218         , m_matrixArrayLayoutFlags(matrixArrayLayoutFlags)
219         , m_numInstances(numInstances)
220     {
221     }
222 
init(void)223     void init(void)
224     {
225         StructType &typeS = m_interface.allocStruct("S");
226         typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
227         typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
228         typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
229 
230         StructType &typeT = m_interface.allocStruct("T");
231         typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
232         typeT.addMember("b", VarType(&typeS));
233 
234         UniformBlock &block = m_interface.allocBlock("Block");
235         block.addUniform(Uniform("s", VarType(&typeS, m_matrixArrayLayoutFlags), 0));
236         block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
237         block.addUniform(Uniform("t", VarType(&typeT, m_matrixLayoutFlags), 0));
238         block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
239         block.setFlags(m_blockLayoutFlags);
240 
241         if (m_numInstances > 0)
242         {
243             block.setInstanceName("block");
244             block.setArraySize(m_numInstances);
245         }
246     }
247 
248 private:
249     uint32_t m_blockLayoutFlags;
250     uint32_t m_matrixLayoutFlags;
251     uint32_t m_matrixArrayLayoutFlags;
252     int m_numInstances;
253 };
254 
255 class BlockSingleNestedStructArrayCase : public UniformBlockCase
256 {
257 public:
BlockSingleNestedStructArrayCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)258     BlockSingleNestedStructArrayCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
259                                      BufferMode bufferMode, int numInstances)
260         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
261                            glu::GLSL_VERSION_300_ES, bufferMode)
262         , m_layoutFlags(layoutFlags)
263         , m_numInstances(numInstances)
264     {
265     }
266 
init(void)267     void init(void)
268     {
269         StructType &typeS = m_interface.allocStruct("S");
270         typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
271         typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
272         typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
273 
274         StructType &typeT = m_interface.allocStruct("T");
275         typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
276         typeT.addMember("b", VarType(VarType(&typeS), 3));
277 
278         UniformBlock &block = m_interface.allocBlock("Block");
279         block.addUniform(Uniform("s", VarType(&typeS), 0));
280         block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
281         block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
282         block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
283         block.setFlags(m_layoutFlags);
284 
285         if (m_numInstances > 0)
286         {
287             block.setInstanceName("block");
288             block.setArraySize(m_numInstances);
289         }
290     }
291 
292 private:
293     uint32_t m_layoutFlags;
294     int m_numInstances;
295 };
296 
297 class BlockMultiBasicTypesCase : public UniformBlockCase
298 {
299 public:
BlockMultiBasicTypesCase(Context & context,const char * name,const char * description,uint32_t flagsA,uint32_t flagsB,BufferMode bufferMode,int numInstances)300     BlockMultiBasicTypesCase(Context &context, const char *name, const char *description, uint32_t flagsA,
301                              uint32_t flagsB, BufferMode bufferMode, int numInstances)
302         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
303                            glu::GLSL_VERSION_300_ES, bufferMode)
304         , m_flagsA(flagsA)
305         , m_flagsB(flagsB)
306         , m_numInstances(numInstances)
307     {
308     }
309 
init(void)310     void init(void)
311     {
312         UniformBlock &blockA = m_interface.allocBlock("BlockA");
313         blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
314         blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
315         blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
316         blockA.setInstanceName("blockA");
317         blockA.setFlags(m_flagsA);
318 
319         UniformBlock &blockB = m_interface.allocBlock("BlockB");
320         blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
321         blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
322         blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
323         blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
324         blockB.setInstanceName("blockB");
325         blockB.setFlags(m_flagsB);
326 
327         if (m_numInstances > 0)
328         {
329             blockA.setArraySize(m_numInstances);
330             blockB.setArraySize(m_numInstances);
331         }
332     }
333 
334 private:
335     uint32_t m_flagsA;
336     uint32_t m_flagsB;
337     int m_numInstances;
338 };
339 
340 class BlockMultiNestedStructCase : public UniformBlockCase
341 {
342 public:
BlockMultiNestedStructCase(Context & context,const char * name,const char * description,uint32_t flagsA,uint32_t flagsB,BufferMode bufferMode,int numInstances)343     BlockMultiNestedStructCase(Context &context, const char *name, const char *description, uint32_t flagsA,
344                                uint32_t flagsB, BufferMode bufferMode, int numInstances)
345         : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description,
346                            glu::GLSL_VERSION_300_ES, bufferMode)
347         , m_flagsA(flagsA)
348         , m_flagsB(flagsB)
349         , m_numInstances(numInstances)
350     {
351     }
352 
init(void)353     void init(void)
354     {
355         StructType &typeS = m_interface.allocStruct("S");
356         typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
357         typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
358         typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
359 
360         StructType &typeT = m_interface.allocStruct("T");
361         typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
362         typeT.addMember("b", VarType(&typeS));
363         typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
364 
365         UniformBlock &blockA = m_interface.allocBlock("BlockA");
366         blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
367         blockA.addUniform(Uniform("b", VarType(&typeS)));
368         blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
369         blockA.setInstanceName("blockA");
370         blockA.setFlags(m_flagsA);
371 
372         UniformBlock &blockB = m_interface.allocBlock("BlockB");
373         blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
374         blockB.addUniform(Uniform("b", VarType(&typeT)));
375         blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
376         blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
377         blockB.setInstanceName("blockB");
378         blockB.setFlags(m_flagsB);
379 
380         if (m_numInstances > 0)
381         {
382             blockA.setArraySize(m_numInstances);
383             blockB.setArraySize(m_numInstances);
384         }
385     }
386 
387 private:
388     uint32_t m_flagsA;
389     uint32_t m_flagsB;
390     int m_numInstances;
391 };
392 
UniformBlockTests(Context & context)393 UniformBlockTests::UniformBlockTests(Context &context) : TestCaseGroup(context, "ubo", "Uniform Block tests")
394 {
395 }
396 
~UniformBlockTests(void)397 UniformBlockTests::~UniformBlockTests(void)
398 {
399 }
400 
init(void)401 void UniformBlockTests::init(void)
402 {
403     static const glu::DataType basicTypes[] = {
404         glu::TYPE_FLOAT,        glu::TYPE_FLOAT_VEC2,   glu::TYPE_FLOAT_VEC3,   glu::TYPE_FLOAT_VEC4,
405         glu::TYPE_INT,          glu::TYPE_INT_VEC2,     glu::TYPE_INT_VEC3,     glu::TYPE_INT_VEC4,
406         glu::TYPE_UINT,         glu::TYPE_UINT_VEC2,    glu::TYPE_UINT_VEC3,    glu::TYPE_UINT_VEC4,
407         glu::TYPE_BOOL,         glu::TYPE_BOOL_VEC2,    glu::TYPE_BOOL_VEC3,    glu::TYPE_BOOL_VEC4,
408         glu::TYPE_FLOAT_MAT2,   glu::TYPE_FLOAT_MAT3,   glu::TYPE_FLOAT_MAT4,   glu::TYPE_FLOAT_MAT2X3,
409         glu::TYPE_FLOAT_MAT2X4, glu::TYPE_FLOAT_MAT3X2, glu::TYPE_FLOAT_MAT3X4, glu::TYPE_FLOAT_MAT4X2,
410         glu::TYPE_FLOAT_MAT4X3};
411 
412     static const struct
413     {
414         const char *name;
415         uint32_t flags;
416     } precisionFlags[] = {{"lowp", PRECISION_LOW}, {"mediump", PRECISION_MEDIUM}, {"highp", PRECISION_HIGH}};
417 
418     static const struct
419     {
420         const char *name;
421         uint32_t flags;
422     } layoutFlags[] = {{"shared", LAYOUT_SHARED}, {"packed", LAYOUT_PACKED}, {"std140", LAYOUT_STD140}};
423 
424     static const struct
425     {
426         const char *name;
427         uint32_t flags;
428     } matrixFlags[] = {{"row_major", LAYOUT_ROW_MAJOR}, {"column_major", LAYOUT_COLUMN_MAJOR}};
429 
430     static const struct
431     {
432         const char *name;
433         UniformBlockCase::BufferMode mode;
434     } bufferModes[] = {{"per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK},
435                        {"single_buffer", UniformBlockCase::BUFFERMODE_SINGLE}};
436 
437     // ubo.single_basic_type
438     {
439         tcu::TestCaseGroup *singleBasicTypeGroup =
440             new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
441         addChild(singleBasicTypeGroup);
442 
443         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
444         {
445             tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
446             singleBasicTypeGroup->addChild(layoutGroup);
447 
448             for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
449             {
450                 glu::DataType type   = basicTypes[basicTypeNdx];
451                 const char *typeName = glu::getDataTypeName(type);
452 
453                 if (glu::isDataTypeBoolOrBVec(type))
454                     createBlockBasicTypeCases(layoutGroup, m_context, typeName, VarType(type, 0),
455                                               layoutFlags[layoutFlagNdx].flags);
456                 else
457                 {
458                     for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
459                         createBlockBasicTypeCases(
460                             layoutGroup, m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(),
461                             VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
462                 }
463 
464                 if (glu::isDataTypeMatrix(type))
465                 {
466                     for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
467                     {
468                         for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
469                             createBlockBasicTypeCases(layoutGroup, m_context,
470                                                       (string(matrixFlags[matFlagNdx].name) + "_" +
471                                                        precisionFlags[precNdx].name + "_" + typeName)
472                                                           .c_str(),
473                                                       VarType(type, precisionFlags[precNdx].flags),
474                                                       layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags);
475                     }
476                 }
477             }
478         }
479     }
480 
481     // ubo.single_basic_array
482     {
483         tcu::TestCaseGroup *singleBasicArrayGroup =
484             new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
485         addChild(singleBasicArrayGroup);
486 
487         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
488         {
489             tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
490             singleBasicArrayGroup->addChild(layoutGroup);
491 
492             for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
493             {
494                 glu::DataType type   = basicTypes[basicTypeNdx];
495                 const char *typeName = glu::getDataTypeName(type);
496                 const int arraySize  = 3;
497 
498                 createBlockBasicTypeCases(
499                     layoutGroup, m_context, typeName,
500                     VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
501                     layoutFlags[layoutFlagNdx].flags);
502 
503                 if (glu::isDataTypeMatrix(type))
504                 {
505                     for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
506                         createBlockBasicTypeCases(layoutGroup, m_context,
507                                                   (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
508                                                   VarType(VarType(type, PRECISION_HIGH), arraySize),
509                                                   layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags);
510                 }
511             }
512         }
513     }
514 
515     // ubo.single_struct
516     {
517         tcu::TestCaseGroup *singleStructGroup =
518             new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
519         addChild(singleStructGroup);
520 
521         for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
522         {
523             tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
524             singleStructGroup->addChild(modeGroup);
525 
526             for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
527             {
528                 for (int isArray = 0; isArray < 2; isArray++)
529                 {
530                     std::string baseName = layoutFlags[layoutFlagNdx].name;
531                     uint32_t baseFlags   = layoutFlags[layoutFlagNdx].flags;
532 
533                     if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
534                         continue; // Doesn't make sense to add this variant.
535 
536                     if (isArray)
537                         baseName += "_instance_array";
538 
539                     modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_vertex").c_str(), "",
540                                                                   baseFlags | DECLARE_VERTEX, bufferModes[modeNdx].mode,
541                                                                   isArray ? 3 : 0));
542                     modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_fragment").c_str(), "",
543                                                                   baseFlags | DECLARE_FRAGMENT,
544                                                                   bufferModes[modeNdx].mode, isArray ? 3 : 0));
545 
546                     if (!(baseFlags & LAYOUT_PACKED))
547                         modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_both").c_str(), "",
548                                                                       baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
549                                                                       bufferModes[modeNdx].mode, isArray ? 3 : 0));
550                 }
551             }
552         }
553     }
554 
555     // ubo.single_struct_array
556     {
557         tcu::TestCaseGroup *singleStructArrayGroup =
558             new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
559         addChild(singleStructArrayGroup);
560 
561         for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
562         {
563             tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
564             singleStructArrayGroup->addChild(modeGroup);
565 
566             for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
567             {
568                 for (int isArray = 0; isArray < 2; isArray++)
569                 {
570                     std::string baseName = layoutFlags[layoutFlagNdx].name;
571                     uint32_t baseFlags   = layoutFlags[layoutFlagNdx].flags;
572 
573                     if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
574                         continue; // Doesn't make sense to add this variant.
575 
576                     if (isArray)
577                         baseName += "_instance_array";
578 
579                     modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_vertex").c_str(), "",
580                                                                        baseFlags | DECLARE_VERTEX,
581                                                                        bufferModes[modeNdx].mode, isArray ? 3 : 0));
582                     modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_fragment").c_str(), "",
583                                                                        baseFlags | DECLARE_FRAGMENT,
584                                                                        bufferModes[modeNdx].mode, isArray ? 3 : 0));
585 
586                     if (!(baseFlags & LAYOUT_PACKED))
587                         modeGroup->addChild(new BlockSingleStructArrayCase(
588                             m_context, (baseName + "_both").c_str(), "", baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
589                             bufferModes[modeNdx].mode, isArray ? 3 : 0));
590                 }
591             }
592         }
593     }
594 
595     // ubo.single_nested_struct
596     {
597         tcu::TestCaseGroup *singleNestedStructGroup =
598             new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
599         addChild(singleNestedStructGroup);
600 
601         for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
602         {
603             tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
604             singleNestedStructGroup->addChild(modeGroup);
605 
606             for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
607             {
608                 for (int isArray = 0; isArray < 2; isArray++)
609                 {
610                     std::string baseName = layoutFlags[layoutFlagNdx].name;
611                     uint32_t baseFlags   = layoutFlags[layoutFlagNdx].flags;
612 
613                     if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
614                         continue; // Doesn't make sense to add this variant.
615 
616                     if (isArray)
617                         baseName += "_instance_array";
618 
619                     modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_vertex").c_str(), "",
620                                                                         baseFlags | DECLARE_VERTEX,
621                                                                         bufferModes[modeNdx].mode, isArray ? 3 : 0));
622                     modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_fragment").c_str(), "",
623                                                                         baseFlags | DECLARE_FRAGMENT,
624                                                                         bufferModes[modeNdx].mode, isArray ? 3 : 0));
625 
626                     if (!(baseFlags & LAYOUT_PACKED))
627                         modeGroup->addChild(new BlockSingleNestedStructCase(
628                             m_context, (baseName + "_both").c_str(), "", baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
629                             bufferModes[modeNdx].mode, isArray ? 3 : 0));
630                 }
631             }
632         }
633     }
634 
635     // ubo.single_nested_struct_mixed_matrix_packing
636     {
637         tcu::TestCaseGroup *singleNestedStructMixedMatrixPackingGroup =
638             new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_mixed_matrix_packing",
639                                    "Nested struct in one uniform block with a mixed matrix packing");
640         addChild(singleNestedStructMixedMatrixPackingGroup);
641 
642         for (const auto &bufferMode : bufferModes)
643         {
644             tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferMode.name, "");
645             singleNestedStructMixedMatrixPackingGroup->addChild(modeGroup);
646 
647             for (const auto &layoutFlag : layoutFlags)
648                 for (const auto &blockMatrixFlag : matrixFlags)
649                     for (const auto &singleMatrixFlag : matrixFlags)
650                         for (const auto &arrayMatrixFlag : matrixFlags)
651                             for (int isArray = 0; isArray < 2; isArray++)
652                             {
653                                 std::string baseName = layoutFlag.name;
654                                 uint32_t baseFlags   = layoutFlag.flags;
655                                 uint32_t blockFlags  = baseFlags | blockMatrixFlag.flags;
656 
657                                 baseName += std::string("_block_") + blockMatrixFlag.name;
658                                 baseName += std::string("_matrix_") + singleMatrixFlag.name;
659                                 baseName += std::string("_matrixarray_") + arrayMatrixFlag.name;
660 
661                                 if (bufferMode.mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
662                                     continue; // Doesn't make sense to add this variant.
663 
664                                 if (isArray)
665                                     baseName += "_instance_array";
666 
667                                 modeGroup->addChild(new BlockSingleNestedStructMixedMatrixPackingCase(
668                                     m_context, (baseName + "_vertex").c_str(), "", blockFlags | DECLARE_VERTEX,
669                                     singleMatrixFlag.flags, arrayMatrixFlag.flags, bufferMode.mode, isArray ? 3 : 0));
670                                 modeGroup->addChild(new BlockSingleNestedStructMixedMatrixPackingCase(
671                                     m_context, (baseName + "_fragment").c_str(), "", blockFlags | DECLARE_FRAGMENT,
672                                     singleMatrixFlag.flags, arrayMatrixFlag.flags, bufferMode.mode, isArray ? 3 : 0));
673 
674                                 if (!(baseFlags & LAYOUT_PACKED))
675                                     modeGroup->addChild(new BlockSingleNestedStructMixedMatrixPackingCase(
676                                         m_context, (baseName + "_both").c_str(), "",
677                                         blockFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, singleMatrixFlag.flags,
678                                         arrayMatrixFlag.flags, bufferMode.mode, isArray ? 3 : 0));
679                             }
680         }
681     }
682 
683     // ubo.single_nested_struct_array
684     {
685         tcu::TestCaseGroup *singleNestedStructArrayGroup =
686             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                     uint32_t 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(
708                         m_context, (baseName + "_vertex").c_str(), "", baseFlags | DECLARE_VERTEX,
709                         bufferModes[modeNdx].mode, isArray ? 3 : 0));
710                     modeGroup->addChild(new BlockSingleNestedStructArrayCase(
711                         m_context, (baseName + "_fragment").c_str(), "", baseFlags | DECLARE_FRAGMENT,
712                         bufferModes[modeNdx].mode, isArray ? 3 : 0));
713 
714                     if (!(baseFlags & LAYOUT_PACKED))
715                         modeGroup->addChild(new BlockSingleNestedStructArrayCase(
716                             m_context, (baseName + "_both").c_str(), "", baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
717                             bufferModes[modeNdx].mode, isArray ? 3 : 0));
718                 }
719             }
720         }
721     }
722 
723     // ubo.instance_array_basic_type
724     {
725         tcu::TestCaseGroup *instanceArrayBasicTypeGroup =
726             new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
727         addChild(instanceArrayBasicTypeGroup);
728 
729         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
730         {
731             tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
732             instanceArrayBasicTypeGroup->addChild(layoutGroup);
733 
734             for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
735             {
736                 glu::DataType type     = basicTypes[basicTypeNdx];
737                 const char *typeName   = glu::getDataTypeName(type);
738                 const int numInstances = 3;
739 
740                 createBlockBasicTypeCases(layoutGroup, m_context, typeName,
741                                           VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
742                                           layoutFlags[layoutFlagNdx].flags, numInstances);
743 
744                 if (glu::isDataTypeMatrix(type))
745                 {
746                     for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
747                         createBlockBasicTypeCases(
748                             layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
749                             VarType(type, PRECISION_HIGH),
750                             layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags, numInstances);
751                 }
752             }
753         }
754     }
755 
756     // ubo.multi_basic_types
757     {
758         tcu::TestCaseGroup *multiBasicTypesGroup =
759             new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
760         addChild(multiBasicTypesGroup);
761 
762         for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
763         {
764             tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
765             multiBasicTypesGroup->addChild(modeGroup);
766 
767             for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
768             {
769                 for (int isArray = 0; isArray < 2; isArray++)
770                 {
771                     std::string baseName = layoutFlags[layoutFlagNdx].name;
772                     uint32_t baseFlags   = layoutFlags[layoutFlagNdx].flags;
773 
774                     if (isArray)
775                         baseName += "_instance_array";
776 
777                     modeGroup->addChild(new BlockMultiBasicTypesCase(
778                         m_context, (baseName + "_vertex").c_str(), "", baseFlags | DECLARE_VERTEX,
779                         baseFlags | DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
780                     modeGroup->addChild(new BlockMultiBasicTypesCase(
781                         m_context, (baseName + "_fragment").c_str(), "", baseFlags | DECLARE_FRAGMENT,
782                         baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
783 
784                     if (!(baseFlags & LAYOUT_PACKED))
785                         modeGroup->addChild(new BlockMultiBasicTypesCase(
786                             m_context, (baseName + "_both").c_str(), "", baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
787                             baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
788 
789                     modeGroup->addChild(new BlockMultiBasicTypesCase(
790                         m_context, (baseName + "_mixed").c_str(), "", baseFlags | DECLARE_VERTEX,
791                         baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
792                 }
793             }
794         }
795     }
796 
797     // ubo.multi_nested_struct
798     {
799         tcu::TestCaseGroup *multiNestedStructGroup =
800             new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
801         addChild(multiNestedStructGroup);
802 
803         for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
804         {
805             tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
806             multiNestedStructGroup->addChild(modeGroup);
807 
808             for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
809             {
810                 for (int isArray = 0; isArray < 2; isArray++)
811                 {
812                     std::string baseName = layoutFlags[layoutFlagNdx].name;
813                     uint32_t baseFlags   = layoutFlags[layoutFlagNdx].flags;
814 
815                     if (isArray)
816                         baseName += "_instance_array";
817 
818                     modeGroup->addChild(new BlockMultiNestedStructCase(
819                         m_context, (baseName + "_vertex").c_str(), "", baseFlags | DECLARE_VERTEX,
820                         baseFlags | DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
821                     modeGroup->addChild(new BlockMultiNestedStructCase(
822                         m_context, (baseName + "_fragment").c_str(), "", baseFlags | DECLARE_FRAGMENT,
823                         baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
824 
825                     if (!(baseFlags & LAYOUT_PACKED))
826                         modeGroup->addChild(new BlockMultiNestedStructCase(
827                             m_context, (baseName + "_both").c_str(), "", baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
828                             baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
829 
830                     modeGroup->addChild(new BlockMultiNestedStructCase(
831                         m_context, (baseName + "_mixed").c_str(), "", baseFlags | DECLARE_VERTEX,
832                         baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
833                 }
834             }
835         }
836     }
837 
838     // ubo.random
839     {
840         const uint32_t allShaders    = FEATURE_VERTEX_BLOCKS | FEATURE_FRAGMENT_BLOCKS | FEATURE_SHARED_BLOCKS;
841         const uint32_t allLayouts    = FEATURE_PACKED_LAYOUT | FEATURE_SHARED_LAYOUT | FEATURE_STD140_LAYOUT;
842         const uint32_t allBasicTypes = FEATURE_VECTORS | FEATURE_MATRICES;
843         const uint32_t unused        = FEATURE_UNUSED_MEMBERS | FEATURE_UNUSED_UNIFORMS;
844         const uint32_t matFlags      = FEATURE_MATRIX_LAYOUT;
845         const uint32_t allFeatures   = ~FEATURE_ARRAYS_OF_ARRAYS;
846 
847         tcu::TestCaseGroup *randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
848         addChild(randomGroup);
849 
850         // Basic types.
851         createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers",
852                               UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused, 25, 0);
853         createRandomCaseGroup(randomGroup, m_context, "vector_types", "Scalar and vector types only, per-block buffers",
854                               UniformBlockCase::BUFFERMODE_PER_BLOCK,
855                               allShaders | allLayouts | unused | FEATURE_VECTORS, 25, 25);
856         createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers",
857                               UniformBlockCase::BUFFERMODE_PER_BLOCK,
858                               allShaders | allLayouts | unused | allBasicTypes | matFlags, 25, 50);
859         createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers",
860                               UniformBlockCase::BUFFERMODE_PER_BLOCK,
861                               allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_ARRAYS, 25, 50);
862 
863         createRandomCaseGroup(randomGroup, m_context, "basic_instance_arrays",
864                               "Basic instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK,
865                               allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_INSTANCE_ARRAYS, 25,
866                               75);
867         createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers",
868                               UniformBlockCase::BUFFERMODE_PER_BLOCK,
869                               allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS, 25, 100);
870         createRandomCaseGroup(
871             randomGroup, m_context, "nested_structs_arrays", "Nested structs, arrays, per-block buffers",
872             UniformBlockCase::BUFFERMODE_PER_BLOCK,
873             allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS | FEATURE_ARRAYS, 25, 150);
874         createRandomCaseGroup(
875             randomGroup, m_context, "nested_structs_instance_arrays",
876             "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK,
877             allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS | FEATURE_INSTANCE_ARRAYS, 25,
878             125);
879         createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays",
880                               "Nested structs, instance arrays, per-block buffers",
881                               UniformBlockCase::BUFFERMODE_PER_BLOCK,
882                               allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS |
883                                   FEATURE_ARRAYS | FEATURE_INSTANCE_ARRAYS,
884                               25, 175);
885 
886         createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers",
887                               UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 200);
888         createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer",
889                               UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 250);
890     }
891 }
892 
893 } // namespace Functional
894 } // namespace gles3
895 } // namespace deqp
896