Merge "x11: Call XInitThreads()" into nougat-cts-dev am: cbdbf95222 am: 6aef236dd0...
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcUniformBlockTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  * Copyright (c) 2016 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */ /*!
21  * \file
22  * \brief Uniform block tests.
23  */ /*-------------------------------------------------------------------*/
24
25 #include "glcUniformBlockTests.hpp"
26 #include "deRandom.hpp"
27 #include "deStringUtil.hpp"
28 #include "glcUniformBlockCase.hpp"
29 #include "tcuCommandLine.hpp"
30
31 namespace deqp
32 {
33
34 using std::string;
35 using std::vector;
36 using deqp::Context;
37
38 using namespace ub;
39
40 enum FeatureBits
41 {
42         FEATURE_VECTORS                 = (1 << 0),
43         FEATURE_MATRICES                = (1 << 1),
44         FEATURE_ARRAYS                  = (1 << 2),
45         FEATURE_STRUCTS                 = (1 << 3),
46         FEATURE_NESTED_STRUCTS  = (1 << 4),
47         FEATURE_INSTANCE_ARRAYS = (1 << 5),
48         FEATURE_VERTEX_BLOCKS   = (1 << 6),
49         FEATURE_FRAGMENT_BLOCKS = (1 << 7),
50         FEATURE_SHARED_BLOCKS   = (1 << 8),
51         FEATURE_UNUSED_UNIFORMS = (1 << 9),
52         FEATURE_UNUSED_MEMBERS  = (1 << 10),
53         FEATURE_PACKED_LAYOUT   = (1 << 11),
54         FEATURE_SHARED_LAYOUT   = (1 << 12),
55         FEATURE_STD140_LAYOUT   = (1 << 13),
56         FEATURE_MATRIX_LAYOUT   = (1 << 14) //!< Matrix layout flags.
57 };
58
59 class RandomUniformBlockCase : public UniformBlockCase
60 {
61 public:
62         RandomUniformBlockCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
63                                                    BufferMode bufferMode, deUint32 features, deUint32 seed);
64
65         void init(void);
66
67 private:
68         void generateBlock(de::Random& rnd, deUint32 layoutFlags);
69         void generateUniform(de::Random& rnd, UniformBlock& block);
70         VarType generateType(de::Random& rnd, int typeDepth, bool arrayOk);
71
72         deUint32 m_features;
73         int              m_maxVertexBlocks;
74         int              m_maxFragmentBlocks;
75         int              m_maxSharedBlocks;
76         int              m_maxInstances;
77         int              m_maxArrayLength;
78         int              m_maxStructDepth;
79         int              m_maxBlockMembers;
80         int              m_maxStructMembers;
81         deUint32 m_seed;
82
83         int m_blockNdx;
84         int m_uniformNdx;
85         int m_structNdx;
86 };
87
88 RandomUniformBlockCase::RandomUniformBlockCase(Context& context, const char* name, const char* description,
89                                                                                            glu::GLSLVersion glslVersion, BufferMode bufferMode, deUint32 features,
90                                                                                            deUint32 seed)
91         : UniformBlockCase(context, name, description, glslVersion, bufferMode)
92         , m_features(features)
93         , m_maxVertexBlocks((features & FEATURE_VERTEX_BLOCKS) ? 4 : 0)
94         , m_maxFragmentBlocks((features & FEATURE_FRAGMENT_BLOCKS) ? 4 : 0)
95         , m_maxSharedBlocks((features & FEATURE_SHARED_BLOCKS) ? 4 : 0)
96         , m_maxInstances((features & FEATURE_INSTANCE_ARRAYS) ? 3 : 0)
97         , m_maxArrayLength((features & FEATURE_ARRAYS) ? 8 : 0)
98         , m_maxStructDepth((features & FEATURE_STRUCTS) ? 2 : 0)
99         , m_maxBlockMembers(5)
100         , m_maxStructMembers(4)
101         , m_seed(seed)
102         , m_blockNdx(1)
103         , m_uniformNdx(1)
104         , m_structNdx(1)
105 {
106 }
107
108 void RandomUniformBlockCase::init(void)
109 {
110         de::Random rnd(m_seed);
111
112         int numShared    = m_maxSharedBlocks > 0 ? rnd.getInt(1, m_maxSharedBlocks) : 0;
113         int numVtxBlocks  = m_maxVertexBlocks - numShared > 0 ? rnd.getInt(1, m_maxVertexBlocks - numShared) : 0;
114         int numFragBlocks = m_maxFragmentBlocks - numShared > 0 ? rnd.getInt(1, m_maxFragmentBlocks - numShared) : 0;
115
116         for (int ndx = 0; ndx < numShared; ndx++)
117                 generateBlock(rnd, DECLARE_VERTEX | DECLARE_FRAGMENT);
118
119         for (int ndx = 0; ndx < numVtxBlocks; ndx++)
120                 generateBlock(rnd, DECLARE_VERTEX);
121
122         for (int ndx = 0; ndx < numFragBlocks; ndx++)
123                 generateBlock(rnd, DECLARE_FRAGMENT);
124 }
125
126 void RandomUniformBlockCase::generateBlock(de::Random& rnd, deUint32 layoutFlags)
127 {
128         DE_ASSERT(m_blockNdx <= 'z' - 'a');
129
130         const float   instanceArrayWeight = 0.3f;
131         UniformBlock& block                               = m_interface.allocBlock((string("Block") + (char)('A' + m_blockNdx)).c_str());
132         int numInstances = (m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, m_maxInstances) : 0;
133         int numUniforms  = rnd.getInt(1, m_maxBlockMembers);
134
135         if (numInstances > 0)
136                 block.setArraySize(numInstances);
137
138         if (numInstances > 0 || rnd.getBool())
139                 block.setInstanceName((string("block") + (char)('A' + m_blockNdx)).c_str());
140
141         // Layout flag candidates.
142         vector<deUint32> layoutFlagCandidates;
143         layoutFlagCandidates.push_back(0);
144         if (m_features & FEATURE_PACKED_LAYOUT)
145                 layoutFlagCandidates.push_back(LAYOUT_SHARED);
146         if ((m_features & FEATURE_SHARED_LAYOUT) && ((layoutFlags & DECLARE_BOTH) != DECLARE_BOTH))
147                 layoutFlagCandidates.push_back(LAYOUT_PACKED); // \note packed layout can only be used in a single shader stage.
148         if (m_features & FEATURE_STD140_LAYOUT)
149                 layoutFlagCandidates.push_back(LAYOUT_STD140);
150
151         layoutFlags |= rnd.choose<deUint32>(layoutFlagCandidates.begin(), layoutFlagCandidates.end());
152
153         if (m_features & FEATURE_MATRIX_LAYOUT)
154         {
155                 static const deUint32 matrixCandidates[] = { 0, LAYOUT_ROW_MAJOR, LAYOUT_COLUMN_MAJOR };
156                 layoutFlags |=
157                         rnd.choose<deUint32>(&matrixCandidates[0], &matrixCandidates[DE_LENGTH_OF_ARRAY(matrixCandidates)]);
158         }
159
160         block.setFlags(layoutFlags);
161
162         for (int ndx = 0; ndx < numUniforms; ndx++)
163                 generateUniform(rnd, block);
164
165         m_blockNdx += 1;
166 }
167
168 static std::string genName(char first, char last, int ndx)
169 {
170         std::string str                 = "";
171         int                     alphabetLen = last - first + 1;
172
173         while (ndx > alphabetLen)
174         {
175                 str.insert(str.begin(), (char)(first + ((ndx - 1) % alphabetLen)));
176                 ndx = ((ndx - 1) / alphabetLen);
177         }
178
179         str.insert(str.begin(), (char)(first + (ndx % (alphabetLen + 1)) - 1));
180
181         return str;
182 }
183
184 void RandomUniformBlockCase::generateUniform(de::Random& rnd, UniformBlock& block)
185 {
186         const float unusedVtxWeight  = 0.15f;
187         const float unusedFragWeight = 0.15f;
188         bool            unusedOk                 = (m_features & FEATURE_UNUSED_UNIFORMS) != 0;
189         deUint32        flags                    = 0;
190         std::string name                         = genName('a', 'z', m_uniformNdx);
191         VarType         type                     = generateType(rnd, 0, true);
192
193         flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? UNUSED_VERTEX : 0;
194         flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? UNUSED_FRAGMENT : 0;
195
196         block.addUniform(Uniform(name.c_str(), type, flags));
197
198         m_uniformNdx += 1;
199 }
200
201 VarType RandomUniformBlockCase::generateType(de::Random& rnd, int typeDepth, bool arrayOk)
202 {
203         const float structWeight = 0.1f;
204         const float arrayWeight  = 0.1f;
205
206         if (typeDepth < m_maxStructDepth && rnd.getFloat() < structWeight)
207         {
208                 const float             unusedVtxWeight  = 0.15f;
209                 const float             unusedFragWeight = 0.15f;
210                 bool                    unusedOk                 = (m_features & FEATURE_UNUSED_MEMBERS) != 0;
211                 vector<VarType> memberTypes;
212                 int                             numMembers = rnd.getInt(1, m_maxStructMembers);
213
214                 // Generate members first so nested struct declarations are in correct order.
215                 for (int ndx = 0; ndx < numMembers; ndx++)
216                         memberTypes.push_back(generateType(rnd, typeDepth + 1, true));
217
218                 StructType& structType = m_interface.allocStruct((string("s") + genName('A', 'Z', m_structNdx)).c_str());
219                 m_structNdx += 1;
220
221                 DE_ASSERT(numMembers <= 'Z' - 'A');
222                 for (int ndx = 0; ndx < numMembers; ndx++)
223                 {
224                         deUint32 flags = 0;
225
226                         flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? UNUSED_VERTEX : 0;
227                         flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? UNUSED_FRAGMENT : 0;
228
229                         structType.addMember((string("m") + (char)('A' + ndx)).c_str(), memberTypes[ndx], flags);
230                 }
231
232                 return VarType(&structType);
233         }
234         else if (m_maxArrayLength > 0 && arrayOk && rnd.getFloat() < arrayWeight)
235         {
236                 int             arrayLength = rnd.getInt(1, m_maxArrayLength);
237                 VarType elementType = generateType(rnd, typeDepth, false /* nested arrays are not allowed */);
238                 return VarType(elementType, arrayLength);
239         }
240         else
241         {
242                 vector<glu::DataType> typeCandidates;
243
244                 typeCandidates.push_back(glu::TYPE_FLOAT);
245                 typeCandidates.push_back(glu::TYPE_INT);
246                 typeCandidates.push_back(glu::TYPE_UINT);
247                 typeCandidates.push_back(glu::TYPE_BOOL);
248
249                 if (m_features & FEATURE_VECTORS)
250                 {
251                         typeCandidates.push_back(glu::TYPE_FLOAT_VEC2);
252                         typeCandidates.push_back(glu::TYPE_FLOAT_VEC3);
253                         typeCandidates.push_back(glu::TYPE_FLOAT_VEC4);
254                         typeCandidates.push_back(glu::TYPE_INT_VEC2);
255                         typeCandidates.push_back(glu::TYPE_INT_VEC3);
256                         typeCandidates.push_back(glu::TYPE_INT_VEC4);
257                         typeCandidates.push_back(glu::TYPE_UINT_VEC2);
258                         typeCandidates.push_back(glu::TYPE_UINT_VEC3);
259                         typeCandidates.push_back(glu::TYPE_UINT_VEC4);
260                         typeCandidates.push_back(glu::TYPE_BOOL_VEC2);
261                         typeCandidates.push_back(glu::TYPE_BOOL_VEC3);
262                         typeCandidates.push_back(glu::TYPE_BOOL_VEC4);
263                 }
264
265                 if (m_features & FEATURE_MATRICES)
266                 {
267                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT2);
268                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT2X3);
269                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X2);
270                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT3);
271                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X4);
272                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X2);
273                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X3);
274                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT4);
275                 }
276
277                 glu::DataType type  = rnd.choose<glu::DataType>(typeCandidates.begin(), typeCandidates.end());
278                 deUint32          flags = 0;
279
280                 if (!glu::isDataTypeBoolOrBVec(type))
281                 {
282                         // Precision.
283                         static const deUint32 precisionCandidates[] = { PRECISION_LOW, PRECISION_MEDIUM, PRECISION_HIGH };
284                         flags |= rnd.choose<deUint32>(&precisionCandidates[0],
285                                                                                   &precisionCandidates[DE_LENGTH_OF_ARRAY(precisionCandidates)]);
286                 }
287
288                 return VarType(type, flags);
289         }
290 }
291
292 class BlockBasicTypeCase : public UniformBlockCase
293 {
294 public:
295         BlockBasicTypeCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
296                                            const VarType& type, deUint32 layoutFlags, int numInstances)
297                 : UniformBlockCase(context, name, description, glslVersion, BUFFERMODE_PER_BLOCK)
298         {
299                 UniformBlock& block = m_interface.allocBlock("Block");
300                 block.addUniform(Uniform("var", type, 0));
301                 block.setFlags(layoutFlags);
302
303                 if (numInstances > 0)
304                 {
305                         block.setArraySize(numInstances);
306                         block.setInstanceName("block");
307                 }
308         }
309 };
310
311 static void createRandomCaseGroup(tcu::TestCaseGroup* parentGroup, Context& context, const char* groupName,
312                                                                   const char* description, glu::GLSLVersion glslVersion,
313                                                                   UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases,
314                                                                   deUint32 baseSeed)
315 {
316         tcu::TestCaseGroup* group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
317         parentGroup->addChild(group);
318
319         baseSeed += (deUint32)context.getTestContext().getCommandLine().getBaseSeed();
320
321         for (int ndx = 0; ndx < numCases; ndx++)
322                 group->addChild(new RandomUniformBlockCase(context, de::toString(ndx).c_str(), "", glslVersion, bufferMode,
323                                                                                                    features, (deUint32)deInt32Hash(ndx + baseSeed)));
324 }
325
326 class BlockSingleStructCase : public UniformBlockCase
327 {
328 public:
329         BlockSingleStructCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
330                                                   deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
331                 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
332                 , m_layoutFlags(layoutFlags)
333                 , m_numInstances(numInstances)
334         {
335         }
336
337         void init(void)
338         {
339                 StructType& typeS = m_interface.allocStruct("S");
340                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
341                 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
342                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
343
344                 UniformBlock& block = m_interface.allocBlock("Block");
345                 block.addUniform(Uniform("s", VarType(&typeS), 0));
346                 block.setFlags(m_layoutFlags);
347
348                 if (m_numInstances > 0)
349                 {
350                         block.setInstanceName("block");
351                         block.setArraySize(m_numInstances);
352                 }
353         }
354
355 private:
356         deUint32 m_layoutFlags;
357         int              m_numInstances;
358 };
359
360 class BlockSingleStructArrayCase : public UniformBlockCase
361 {
362 public:
363         BlockSingleStructArrayCase(Context& context, const char* name, const char* description,
364                                                            glu::GLSLVersion glslVersion, deUint32 layoutFlags, BufferMode bufferMode,
365                                                            int numInstances)
366                 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
367                 , m_layoutFlags(layoutFlags)
368                 , m_numInstances(numInstances)
369         {
370         }
371
372         void init(void)
373         {
374                 StructType& typeS = m_interface.allocStruct("S");
375                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
376                 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
377                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
378
379                 UniformBlock& block = m_interface.allocBlock("Block");
380                 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
381                 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
382                 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
383                 block.setFlags(m_layoutFlags);
384
385                 if (m_numInstances > 0)
386                 {
387                         block.setInstanceName("block");
388                         block.setArraySize(m_numInstances);
389                 }
390         }
391
392 private:
393         deUint32 m_layoutFlags;
394         int              m_numInstances;
395 };
396
397 class BlockSingleNestedStructCase : public UniformBlockCase
398 {
399 public:
400         BlockSingleNestedStructCase(Context& context, const char* name, const char* description,
401                                                                 glu::GLSLVersion glslVersion, deUint32 layoutFlags, BufferMode bufferMode,
402                                                                 int numInstances)
403                 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
404                 , m_layoutFlags(layoutFlags)
405                 , m_numInstances(numInstances)
406         {
407         }
408
409         void init(void)
410         {
411                 StructType& typeS = m_interface.allocStruct("S");
412                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
413                 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
414                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
415
416                 StructType& typeT = m_interface.allocStruct("T");
417                 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
418                 typeT.addMember("b", VarType(&typeS));
419
420                 UniformBlock& block = m_interface.allocBlock("Block");
421                 block.addUniform(Uniform("s", VarType(&typeS), 0));
422                 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
423                 block.addUniform(Uniform("t", VarType(&typeT), 0));
424                 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
425                 block.setFlags(m_layoutFlags);
426
427                 if (m_numInstances > 0)
428                 {
429                         block.setInstanceName("block");
430                         block.setArraySize(m_numInstances);
431                 }
432         }
433
434 private:
435         deUint32 m_layoutFlags;
436         int              m_numInstances;
437 };
438
439 class BlockSingleNestedStructArrayCase : public UniformBlockCase
440 {
441 public:
442         BlockSingleNestedStructArrayCase(Context& context, const char* name, const char* description,
443                                                                          glu::GLSLVersion glslVersion, deUint32 layoutFlags, BufferMode bufferMode,
444                                                                          int numInstances)
445                 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
446                 , m_layoutFlags(layoutFlags)
447                 , m_numInstances(numInstances)
448         {
449         }
450
451         void init(void)
452         {
453                 StructType& typeS = m_interface.allocStruct("S");
454                 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
455                 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
456                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
457
458                 StructType& typeT = m_interface.allocStruct("T");
459                 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
460                 typeT.addMember("b", VarType(VarType(&typeS), 3));
461
462                 UniformBlock& block = m_interface.allocBlock("Block");
463                 block.addUniform(Uniform("s", VarType(&typeS), 0));
464                 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
465                 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
466                 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
467                 block.setFlags(m_layoutFlags);
468
469                 if (m_numInstances > 0)
470                 {
471                         block.setInstanceName("block");
472                         block.setArraySize(m_numInstances);
473                 }
474         }
475
476 private:
477         deUint32 m_layoutFlags;
478         int              m_numInstances;
479 };
480
481 class BlockMultiBasicTypesCase : public UniformBlockCase
482 {
483 public:
484         BlockMultiBasicTypesCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
485                                                          deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
486                 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
487                 , m_flagsA(flagsA)
488                 , m_flagsB(flagsB)
489                 , m_numInstances(numInstances)
490         {
491         }
492
493         void init(void)
494         {
495                 UniformBlock& blockA = m_interface.allocBlock("BlockA");
496                 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
497                 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
498                 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
499                 blockA.setInstanceName("blockA");
500                 blockA.setFlags(m_flagsA);
501
502                 UniformBlock& blockB = m_interface.allocBlock("BlockB");
503                 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
504                 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
505                 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
506                 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
507                 blockB.setInstanceName("blockB");
508                 blockB.setFlags(m_flagsB);
509
510                 if (m_numInstances > 0)
511                 {
512                         blockA.setArraySize(m_numInstances);
513                         blockB.setArraySize(m_numInstances);
514                 }
515         }
516
517 private:
518         deUint32 m_flagsA;
519         deUint32 m_flagsB;
520         int              m_numInstances;
521 };
522
523 class BlockMultiNestedStructCase : public UniformBlockCase
524 {
525 public:
526         BlockMultiNestedStructCase(Context& context, const char* name, const char* description,
527                                                            glu::GLSLVersion glslVersion, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode,
528                                                            int numInstances)
529                 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
530                 , m_flagsA(flagsA)
531                 , m_flagsB(flagsB)
532                 , m_numInstances(numInstances)
533         {
534         }
535
536         void init(void)
537         {
538                 StructType& typeS = m_interface.allocStruct("S");
539                 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
540                 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
541                 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
542
543                 StructType& typeT = m_interface.allocStruct("T");
544                 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
545                 typeT.addMember("b", VarType(&typeS));
546                 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
547
548                 UniformBlock& blockA = m_interface.allocBlock("BlockA");
549                 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
550                 blockA.addUniform(Uniform("b", VarType(&typeS)));
551                 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
552                 blockA.setInstanceName("blockA");
553                 blockA.setFlags(m_flagsA);
554
555                 UniformBlock& blockB = m_interface.allocBlock("BlockB");
556                 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
557                 blockB.addUniform(Uniform("b", VarType(&typeT)));
558                 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
559                 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
560                 blockB.setInstanceName("blockB");
561                 blockB.setFlags(m_flagsB);
562
563                 if (m_numInstances > 0)
564                 {
565                         blockA.setArraySize(m_numInstances);
566                         blockB.setArraySize(m_numInstances);
567                 }
568         }
569
570 private:
571         deUint32 m_flagsA;
572         deUint32 m_flagsB;
573         int              m_numInstances;
574 };
575
576 UniformBlockTests::UniformBlockTests(Context& context, glu::GLSLVersion glslVersion)
577         : TestCaseGroup(context, "uniform_block", "Uniform Block tests"), m_glslVersion(glslVersion)
578 {
579 }
580
581 UniformBlockTests::~UniformBlockTests(void)
582 {
583 }
584
585 void UniformBlockTests::init(void)
586 {
587         static const glu::DataType basicTypes[] = { glu::TYPE_FLOAT,            glu::TYPE_FLOAT_VEC2,   glu::TYPE_FLOAT_VEC3,
588                                                                                                 glu::TYPE_FLOAT_VEC4,   glu::TYPE_INT,                  glu::TYPE_INT_VEC2,
589                                                                                                 glu::TYPE_INT_VEC3,             glu::TYPE_INT_VEC4,             glu::TYPE_UINT,
590                                                                                                 glu::TYPE_UINT_VEC2,    glu::TYPE_UINT_VEC3,    glu::TYPE_UINT_VEC4,
591                                                                                                 glu::TYPE_BOOL,                 glu::TYPE_BOOL_VEC2,    glu::TYPE_BOOL_VEC3,
592                                                                                                 glu::TYPE_BOOL_VEC4,    glu::TYPE_FLOAT_MAT2,   glu::TYPE_FLOAT_MAT3,
593                                                                                                 glu::TYPE_FLOAT_MAT4,   glu::TYPE_FLOAT_MAT2X3, glu::TYPE_FLOAT_MAT2X4,
594                                                                                                 glu::TYPE_FLOAT_MAT3X2, glu::TYPE_FLOAT_MAT3X4, glu::TYPE_FLOAT_MAT4X2,
595                                                                                                 glu::TYPE_FLOAT_MAT4X3 };
596
597         static const struct
598         {
599                 const char* name;
600                 deUint32        flags;
601         } precisionFlags[] = { { "lowp", PRECISION_LOW }, { "mediump", PRECISION_MEDIUM }, { "highp", PRECISION_HIGH } };
602
603         static const struct
604         {
605                 const char* name;
606                 deUint32        flags;
607         } layoutFlags[] = { { "shared", LAYOUT_SHARED }, { "packed", LAYOUT_PACKED }, { "std140", LAYOUT_STD140 } };
608
609         static const struct
610         {
611                 const char* name;
612                 deUint32        flags;
613         } matrixFlags[] = { { "row_major", LAYOUT_ROW_MAJOR }, { "column_major", LAYOUT_COLUMN_MAJOR } };
614
615         static const struct
616         {
617                 const char*                                      name;
618                 UniformBlockCase::BufferMode mode;
619         } bufferModes[] = { { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
620                                                 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE } };
621
622         // ubo.single_basic_type
623         {
624                 tcu::TestCaseGroup* singleBasicTypeGroup =
625                         new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
626                 addChild(singleBasicTypeGroup);
627
628                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
629                 {
630                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
631                         singleBasicTypeGroup->addChild(layoutGroup);
632
633                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
634                         {
635                                 glu::DataType type              = basicTypes[basicTypeNdx];
636                                 const char*   typeName  = glu::getDataTypeName(type);
637                                 deUint32          baseFlags = layoutFlags[layoutFlagNdx].flags;
638                                 deUint32          flags         = baseFlags | ((baseFlags & LAYOUT_PACKED) ?
639                                                                                                   (basicTypeNdx % 2 == 0 ? DECLARE_VERTEX : DECLARE_FRAGMENT) :
640                                                                                                   DECLARE_BOTH);
641
642                                 if (glu::isDataTypeBoolOrBVec(type))
643                                         layoutGroup->addChild(new BlockBasicTypeCase(m_context, typeName, "", m_glslVersion,
644                                                                                                                                  VarType(type, 0), flags, 0 /* no instance array */));
645                                 else
646                                 {
647                                         for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
648                                                 layoutGroup->addChild(new BlockBasicTypeCase(
649                                                         m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(), "",
650                                                         m_glslVersion, VarType(type, precisionFlags[precNdx].flags), flags,
651                                                         0 /* no instance array */));
652                                 }
653
654                                 if (glu::isDataTypeMatrix(type))
655                                 {
656                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
657                                         {
658                                                 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
659                                                         layoutGroup->addChild(new BlockBasicTypeCase(
660                                                                 m_context,
661                                                                 (string(matrixFlags[matFlagNdx].name) + "_" + precisionFlags[precNdx].name + "_" +
662                                                                  typeName)
663                                                                         .c_str(),
664                                                                 "", m_glslVersion, VarType(type, precisionFlags[precNdx].flags),
665                                                                 flags | matrixFlags[matFlagNdx].flags, 0 /* no instance array */));
666                                         }
667                                 }
668                         }
669                 }
670         }
671
672         // ubo.single_basic_array
673         {
674                 tcu::TestCaseGroup* singleBasicArrayGroup =
675                         new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
676                 addChild(singleBasicArrayGroup);
677
678                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
679                 {
680                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
681                         singleBasicArrayGroup->addChild(layoutGroup);
682
683                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
684                         {
685                                 glu::DataType type              = basicTypes[basicTypeNdx];
686                                 const char*   typeName  = glu::getDataTypeName(type);
687                                 const int        arraySize = 3;
688                                 deUint32          baseFlags = layoutFlags[layoutFlagNdx].flags;
689                                 deUint32          flags         = baseFlags | ((baseFlags & LAYOUT_PACKED) ?
690                                                                                                   (basicTypeNdx % 2 == 0 ? DECLARE_VERTEX : DECLARE_FRAGMENT) :
691                                                                                                   DECLARE_BOTH);
692
693                                 layoutGroup->addChild(new BlockBasicTypeCase(
694                                         m_context, typeName, "", m_glslVersion,
695                                         VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize), flags,
696                                         0 /* no instance array */));
697
698                                 if (glu::isDataTypeMatrix(type))
699                                 {
700                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
701                                                 layoutGroup->addChild(new BlockBasicTypeCase(
702                                                         m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "",
703                                                         m_glslVersion, VarType(VarType(type, PRECISION_HIGH), arraySize),
704                                                         flags | matrixFlags[matFlagNdx].flags, 0 /* no instance array */));
705                                 }
706                         }
707                 }
708         }
709
710         // ubo.single_struct
711         {
712                 tcu::TestCaseGroup* singleStructGroup =
713                         new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
714                 addChild(singleStructGroup);
715
716                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
717                 {
718                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
719                         {
720                                 for (int isArray = 0; isArray < 2; isArray++)
721                                 {
722                                         std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
723                                         deUint32        baseFlags = layoutFlags[layoutFlagNdx].flags;
724                                         deUint32        flags    = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_VERTEX : DECLARE_BOTH);
725
726                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
727                                                 continue; // Doesn't make sense to add this variant.
728
729                                         if (isArray)
730                                                 name += "_instance_array";
731
732                                         singleStructGroup->addChild(new BlockSingleStructCase(
733                                                 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
734                                 }
735                         }
736                 }
737         }
738
739         // ubo.single_struct_array
740         {
741                 tcu::TestCaseGroup* singleStructArrayGroup =
742                         new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
743                 addChild(singleStructArrayGroup);
744
745                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
746                 {
747                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
748                         {
749                                 for (int isArray = 0; isArray < 2; isArray++)
750                                 {
751                                         std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
752                                         deUint32        baseFlags = layoutFlags[layoutFlagNdx].flags;
753                                         deUint32        flags    = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_FRAGMENT : DECLARE_BOTH);
754
755                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
756                                                 continue; // Doesn't make sense to add this variant.
757
758                                         if (isArray)
759                                                 name += "_instance_array";
760
761                                         singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(
762                                                 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
763                                 }
764                         }
765                 }
766         }
767
768         // ubo.single_nested_struct
769         {
770                 tcu::TestCaseGroup* singleNestedStructGroup =
771                         new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
772                 addChild(singleNestedStructGroup);
773
774                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
775                 {
776                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
777                         {
778                                 for (int isArray = 0; isArray < 2; isArray++)
779                                 {
780                                         std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
781                                         deUint32        baseFlags = layoutFlags[layoutFlagNdx].flags;
782                                         deUint32        flags    = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_VERTEX : DECLARE_BOTH);
783
784                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
785                                                 continue; // Doesn't make sense to add this variant.
786
787                                         if (isArray)
788                                                 name += "_instance_array";
789
790                                         singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(
791                                                 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
792                                 }
793                         }
794                 }
795         }
796
797         // ubo.single_nested_struct_array
798         {
799                 tcu::TestCaseGroup* singleNestedStructArrayGroup =
800                         new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
801                 addChild(singleNestedStructArrayGroup);
802
803                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
804                 {
805                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
806                         {
807                                 for (int isArray = 0; isArray < 2; isArray++)
808                                 {
809                                         std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
810                                         deUint32        baseFlags = layoutFlags[layoutFlagNdx].flags;
811                                         deUint32        flags    = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_FRAGMENT : DECLARE_BOTH);
812
813                                         if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
814                                                 continue; // Doesn't make sense to add this variant.
815
816                                         if (isArray)
817                                                 name += "_instance_array";
818
819                                         singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(
820                                                 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
821                                 }
822                         }
823                 }
824         }
825
826         // ubo.instance_array_basic_type
827         {
828                 tcu::TestCaseGroup* instanceArrayBasicTypeGroup =
829                         new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
830                 addChild(instanceArrayBasicTypeGroup);
831
832                 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
833                 {
834                         tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
835                         instanceArrayBasicTypeGroup->addChild(layoutGroup);
836
837                         for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
838                         {
839                                 glu::DataType type                 = basicTypes[basicTypeNdx];
840                                 const char*   typeName   = glu::getDataTypeName(type);
841                                 const int        numInstances = 3;
842                                 deUint32          baseFlags     = layoutFlags[layoutFlagNdx].flags;
843                                 deUint32          flags            = baseFlags | ((baseFlags & LAYOUT_PACKED) ?
844                                                                                                   (basicTypeNdx % 2 == 0 ? DECLARE_VERTEX : DECLARE_FRAGMENT) :
845                                                                                                   DECLARE_BOTH);
846
847                                 layoutGroup->addChild(new BlockBasicTypeCase(
848                                         m_context, typeName, "", m_glslVersion,
849                                         VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), flags, numInstances));
850
851                                 if (glu::isDataTypeMatrix(type))
852                                 {
853                                         for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
854                                                 layoutGroup->addChild(new BlockBasicTypeCase(
855                                                         m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "",
856                                                         m_glslVersion, VarType(type, PRECISION_HIGH), flags | matrixFlags[matFlagNdx].flags,
857                                                         numInstances));
858                                 }
859                         }
860                 }
861         }
862
863         // ubo.multi_basic_types
864         {
865                 tcu::TestCaseGroup* multiBasicTypesGroup =
866                         new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
867                 addChild(multiBasicTypesGroup);
868
869                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
870                 {
871                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
872                         multiBasicTypesGroup->addChild(modeGroup);
873
874                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
875                         {
876                                 for (int isArray = 0; isArray < 2; isArray++)
877                                 {
878                                         std::string baseName  = layoutFlags[layoutFlagNdx].name;
879                                         deUint32        baseFlags = layoutFlags[layoutFlagNdx].flags;
880
881                                         if (isArray)
882                                                 baseName += "_instance_array";
883
884                                         modeGroup->addChild(new BlockMultiBasicTypesCase(
885                                                 m_context, (baseName + "_mixed").c_str(), "", m_glslVersion, baseFlags | DECLARE_VERTEX,
886                                                 baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
887
888                                         if (!(baseFlags & LAYOUT_PACKED))
889                                                 modeGroup->addChild(new BlockMultiBasicTypesCase(
890                                                         m_context, (baseName + "_both").c_str(), "", m_glslVersion,
891                                                         baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
892                                                         baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
893                                 }
894                         }
895                 }
896         }
897
898         // ubo.multi_nested_struct
899         {
900                 tcu::TestCaseGroup* multiNestedStructGroup =
901                         new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
902                 addChild(multiNestedStructGroup);
903
904                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
905                 {
906                         tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
907                         multiNestedStructGroup->addChild(modeGroup);
908
909                         for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
910                         {
911                                 for (int isArray = 0; isArray < 2; isArray++)
912                                 {
913                                         std::string baseName  = layoutFlags[layoutFlagNdx].name;
914                                         deUint32        baseFlags = layoutFlags[layoutFlagNdx].flags;
915
916                                         if (isArray)
917                                                 baseName += "_instance_array";
918
919                                         modeGroup->addChild(new BlockMultiNestedStructCase(
920                                                 m_context, (baseName + "_mixed").c_str(), "", m_glslVersion, baseFlags | DECLARE_VERTEX,
921                                                 baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
922
923                                         if (!(baseFlags & LAYOUT_PACKED))
924                                                 modeGroup->addChild(new BlockMultiNestedStructCase(
925                                                         m_context, (baseName + "_both").c_str(), "", m_glslVersion,
926                                                         baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
927                                                         baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
928                                 }
929                         }
930                 }
931         }
932
933         // ubo.random
934         {
935                 const deUint32 allShaders       = FEATURE_VERTEX_BLOCKS | FEATURE_FRAGMENT_BLOCKS | FEATURE_SHARED_BLOCKS;
936                 const deUint32 allLayouts       = FEATURE_PACKED_LAYOUT | FEATURE_SHARED_LAYOUT | FEATURE_STD140_LAYOUT;
937                 const deUint32 allBasicTypes = FEATURE_VECTORS | FEATURE_MATRICES;
938                 const deUint32 unused            = FEATURE_UNUSED_MEMBERS | FEATURE_UNUSED_UNIFORMS;
939                 const deUint32 matFlags          = FEATURE_MATRIX_LAYOUT;
940
941                 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
942                 addChild(randomGroup);
943
944                 // Basic types.
945                 createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers",
946                                                           m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused,
947                                                           10, 0);
948                 createRandomCaseGroup(randomGroup, m_context, "vector_types", "Scalar and vector types only, per-block buffers",
949                                                           m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
950                                                           allShaders | allLayouts | unused | FEATURE_VECTORS, 10, 25);
951                 createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers",
952                                                           m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
953                                                           allShaders | allLayouts | unused | allBasicTypes | matFlags, 10, 50);
954                 createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers", m_glslVersion,
955                                                           UniformBlockCase::BUFFERMODE_PER_BLOCK,
956                                                           allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_ARRAYS, 10, 50);
957
958                 createRandomCaseGroup(
959                         randomGroup, m_context, "basic_instance_arrays", "Basic instance arrays, per-block buffers", m_glslVersion,
960                         UniformBlockCase::BUFFERMODE_PER_BLOCK,
961                         allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_INSTANCE_ARRAYS, 10, 75);
962                 createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers",
963                                                           m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
964                                                           allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS, 10, 100);
965                 createRandomCaseGroup(
966                         randomGroup, m_context, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", m_glslVersion,
967                         UniformBlockCase::BUFFERMODE_PER_BLOCK,
968                         allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS | FEATURE_ARRAYS, 10, 150);
969                 createRandomCaseGroup(
970                         randomGroup, m_context, "nested_structs_instance_arrays",
971                         "Nested structs, instance arrays, per-block buffers", m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
972                         allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS | FEATURE_INSTANCE_ARRAYS, 10,
973                         125);
974                 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays",
975                                                           "Nested structs, instance arrays, per-block buffers", m_glslVersion,
976                                                           UniformBlockCase::BUFFERMODE_PER_BLOCK,
977                                                           allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS |
978                                                                   FEATURE_ARRAYS | FEATURE_INSTANCE_ARRAYS,
979                                                           10, 175);
980
981                 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers",
982                                                           m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK, ~0u, 20, 200);
983                 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer",
984                                                           m_glslVersion, UniformBlockCase::BUFFERMODE_SINGLE, ~0u, 20, 250);
985         }
986 }
987
988 } // deqp