1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 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 SSBO layout tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fSSBOLayoutTests.hpp"
25 #include "es31fSSBOLayoutCase.hpp"
26 #include "tcuCommandLine.hpp"
27 #include "deRandom.hpp"
28 #include "deStringUtil.hpp"
29 #include "deString.h"
30
31 using std::string;
32 using std::vector;
33
34 namespace deqp
35 {
36 namespace gles31
37 {
38 namespace Functional
39 {
40
41 using namespace bb;
42 using glu::StructType;
43 using glu::VarType;
44
45 namespace
46 {
47
48 enum FeatureBits
49 {
50 FEATURE_VECTORS = (1 << 0),
51 FEATURE_MATRICES = (1 << 1),
52 FEATURE_ARRAYS = (1 << 2),
53 FEATURE_STRUCTS = (1 << 3),
54 FEATURE_NESTED_STRUCTS = (1 << 4),
55 FEATURE_INSTANCE_ARRAYS = (1 << 5),
56 FEATURE_UNUSED_VARS = (1 << 6),
57 FEATURE_UNUSED_MEMBERS = (1 << 7),
58 FEATURE_PACKED_LAYOUT = (1 << 8),
59 FEATURE_SHARED_LAYOUT = (1 << 9),
60 FEATURE_STD140_LAYOUT = (1 << 10),
61 FEATURE_STD430_LAYOUT = (1 << 11),
62 FEATURE_MATRIX_LAYOUT = (1 << 12), //!< Matrix layout flags.
63 FEATURE_UNSIZED_ARRAYS = (1 << 13),
64 FEATURE_ARRAYS_OF_ARRAYS = (1 << 14)
65 };
66
67 class RandomSSBOLayoutCase : public SSBOLayoutCase
68 {
69 public:
70 RandomSSBOLayoutCase(Context &context, const char *name, const char *description, BufferMode bufferMode,
71 uint32_t features, uint32_t seed);
72
73 void init(void);
74
75 private:
76 void generateBlock(de::Random &rnd, uint32_t layoutFlags);
77 void generateBufferVar(de::Random &rnd, BufferBlock &block, bool isLastMember);
78 glu::VarType generateType(de::Random &rnd, int structDepth, int arrayDepth, bool arrayOk, bool unusedArrayOk);
79
80 uint32_t m_features;
81 int m_maxBlocks;
82 int m_maxInstances;
83 int m_maxArrayLength;
84 int m_maxArrayDepth;
85 int m_maxStructDepth;
86 int m_maxBlockMembers;
87 int m_maxStructMembers;
88 uint32_t m_seed;
89
90 int m_blockNdx;
91 int m_bufferVarNdx;
92 int m_structNdx;
93 };
94
RandomSSBOLayoutCase(Context & context,const char * name,const char * description,BufferMode bufferMode,uint32_t features,uint32_t seed)95 RandomSSBOLayoutCase::RandomSSBOLayoutCase(Context &context, const char *name, const char *description,
96 BufferMode bufferMode, uint32_t features, uint32_t seed)
97 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_310_ES,
98 bufferMode)
99 , m_features(features)
100 , m_maxBlocks(3)
101 , m_maxInstances((features & FEATURE_INSTANCE_ARRAYS) ? 3 : 0)
102 , m_maxArrayLength((features & FEATURE_ARRAYS) ? 8 : 0)
103 , m_maxArrayDepth((features & FEATURE_ARRAYS_OF_ARRAYS) ? 2 : 0)
104 , m_maxStructDepth((features & FEATURE_STRUCTS) ? 2 : 0)
105 , m_maxBlockMembers(4)
106 , m_maxStructMembers(4)
107 , m_seed(seed)
108 , m_blockNdx(1)
109 , m_bufferVarNdx(1)
110 , m_structNdx(1)
111 {
112 }
113
init(void)114 void RandomSSBOLayoutCase::init(void)
115 {
116 de::Random rnd(m_seed);
117
118 const int numBlocks = rnd.getInt(1, m_maxBlocks);
119
120 for (int ndx = 0; ndx < numBlocks; ndx++)
121 generateBlock(rnd, 0);
122 }
123
generateBlock(de::Random & rnd,uint32_t layoutFlags)124 void RandomSSBOLayoutCase::generateBlock(de::Random &rnd, uint32_t layoutFlags)
125 {
126 DE_ASSERT(m_blockNdx <= 'z' - 'a');
127
128 const float instanceArrayWeight = 0.3f;
129 BufferBlock &block = m_interface.allocBlock((string("Block") + (char)('A' + m_blockNdx)).c_str());
130 int numInstances = (m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, m_maxInstances) : 0;
131 int numVars = rnd.getInt(1, m_maxBlockMembers);
132
133 if (numInstances > 0)
134 block.setArraySize(numInstances);
135
136 if (numInstances > 0 || rnd.getBool())
137 block.setInstanceName((string("block") + (char)('A' + m_blockNdx)).c_str());
138
139 // Layout flag candidates.
140 vector<uint32_t> layoutFlagCandidates;
141 layoutFlagCandidates.push_back(0);
142 if (m_features & FEATURE_PACKED_LAYOUT)
143 layoutFlagCandidates.push_back(LAYOUT_PACKED);
144 if ((m_features & FEATURE_SHARED_LAYOUT))
145 layoutFlagCandidates.push_back(LAYOUT_SHARED);
146 if (m_features & FEATURE_STD140_LAYOUT)
147 layoutFlagCandidates.push_back(LAYOUT_STD140);
148
149 layoutFlags |= rnd.choose<uint32_t>(layoutFlagCandidates.begin(), layoutFlagCandidates.end());
150
151 if (m_features & FEATURE_MATRIX_LAYOUT)
152 {
153 static const uint32_t matrixCandidates[] = {0, LAYOUT_ROW_MAJOR, LAYOUT_COLUMN_MAJOR};
154 layoutFlags |=
155 rnd.choose<uint32_t>(&matrixCandidates[0], &matrixCandidates[DE_LENGTH_OF_ARRAY(matrixCandidates)]);
156 }
157
158 block.setFlags(layoutFlags);
159
160 for (int ndx = 0; ndx < numVars; ndx++)
161 generateBufferVar(rnd, block, (ndx + 1 == numVars));
162
163 if (numVars > 0)
164 {
165 const BufferVar &lastVar = *(block.end() - 1);
166 const glu::VarType &lastType = lastVar.getType();
167 const bool isUnsizedArr = lastType.isArrayType() && (lastType.getArraySize() == glu::VarType::UNSIZED_ARRAY);
168
169 if (isUnsizedArr)
170 {
171 for (int instanceNdx = 0; instanceNdx < (numInstances ? numInstances : 1); instanceNdx++)
172 {
173 const int arrSize = rnd.getInt(0, m_maxArrayLength);
174 block.setLastUnsizedArraySize(instanceNdx, arrSize);
175 }
176 }
177 }
178
179 m_blockNdx += 1;
180 }
181
genName(char first,char last,int ndx)182 static std::string genName(char first, char last, int ndx)
183 {
184 std::string str = "";
185 int alphabetLen = last - first + 1;
186
187 while (ndx > alphabetLen)
188 {
189 str.insert(str.begin(), (char)(first + ((ndx - 1) % alphabetLen)));
190 ndx = ((ndx - 1) / alphabetLen);
191 }
192
193 str.insert(str.begin(), (char)(first + (ndx % (alphabetLen + 1)) - 1));
194
195 return str;
196 }
197
generateBufferVar(de::Random & rnd,BufferBlock & block,bool isLastMember)198 void RandomSSBOLayoutCase::generateBufferVar(de::Random &rnd, BufferBlock &block, bool isLastMember)
199 {
200 const float readWeight = 0.7f;
201 const float writeWeight = 0.7f;
202 const float accessWeight = 0.85f;
203 const bool unusedOk = (m_features & FEATURE_UNUSED_VARS) != 0;
204 const std::string name = genName('a', 'z', m_bufferVarNdx);
205 const glu::VarType type = generateType(rnd, 0, 0, true, isLastMember && (m_features & FEATURE_UNSIZED_ARRAYS));
206 const bool access = !unusedOk || (rnd.getFloat() < accessWeight);
207 const bool read = access ? (rnd.getFloat() < readWeight) : false;
208 const bool write = access ? (!read || (rnd.getFloat() < writeWeight)) : false;
209 const uint32_t flags = (read ? ACCESS_READ : 0) | (write ? ACCESS_WRITE : 0);
210
211 block.addMember(BufferVar(name.c_str(), type, flags));
212
213 m_bufferVarNdx += 1;
214 }
215
generateType(de::Random & rnd,int structDepth,int arrayDepth,bool arrayOk,bool unsizedArrayOk)216 glu::VarType RandomSSBOLayoutCase::generateType(de::Random &rnd, int structDepth, int arrayDepth, bool arrayOk,
217 bool unsizedArrayOk)
218 {
219 const float structWeight = 0.1f;
220 const float arrayWeight = 0.1f;
221 const float unsizedArrayWeight = 0.8f;
222
223 DE_ASSERT(arrayOk || !unsizedArrayOk);
224
225 if (unsizedArrayOk && (rnd.getFloat() < unsizedArrayWeight))
226 {
227 const bool childArrayOk = ((m_features & FEATURE_ARRAYS_OF_ARRAYS) != 0) && (arrayDepth < m_maxArrayDepth);
228 const glu::VarType elementType = generateType(rnd, structDepth, arrayDepth + 1, childArrayOk, false);
229 return glu::VarType(elementType, glu::VarType::UNSIZED_ARRAY);
230 }
231 else if (structDepth < m_maxStructDepth && rnd.getFloat() < structWeight)
232 {
233 // \todo [2013-10-14 pyry] Implement unused flags for members!
234 // bool unusedOk = (m_features & FEATURE_UNUSED_MEMBERS) != 0;
235 vector<glu::VarType> memberTypes;
236 int numMembers = rnd.getInt(1, m_maxStructMembers);
237
238 // Generate members first so nested struct declarations are in correct order.
239 for (int ndx = 0; ndx < numMembers; ndx++)
240 memberTypes.push_back(
241 generateType(rnd, structDepth + 1, arrayDepth, (arrayDepth < m_maxArrayDepth), false));
242
243 glu::StructType &structType = m_interface.allocStruct((string("s") + genName('A', 'Z', m_structNdx)).c_str());
244 m_structNdx += 1;
245
246 DE_ASSERT(numMembers <= 'Z' - 'A');
247 for (int ndx = 0; ndx < numMembers; ndx++)
248 {
249 structType.addMember((string("m") + (char)('A' + ndx)).c_str(), memberTypes[ndx]);
250 }
251
252 return glu::VarType(&structType);
253 }
254 else if (m_maxArrayLength > 0 && arrayOk && rnd.getFloat() < arrayWeight)
255 {
256 const int arrayLength = rnd.getInt(1, m_maxArrayLength);
257 const bool childArrayOk = ((m_features & FEATURE_ARRAYS_OF_ARRAYS) != 0) && (arrayDepth < m_maxArrayDepth);
258 const glu::VarType elementType = generateType(rnd, structDepth, arrayDepth + 1, childArrayOk, false);
259
260 return glu::VarType(elementType, arrayLength);
261 }
262 else
263 {
264 vector<glu::DataType> typeCandidates;
265
266 typeCandidates.push_back(glu::TYPE_FLOAT);
267 typeCandidates.push_back(glu::TYPE_INT);
268 typeCandidates.push_back(glu::TYPE_UINT);
269 typeCandidates.push_back(glu::TYPE_BOOL);
270
271 if (m_features & FEATURE_VECTORS)
272 {
273 typeCandidates.push_back(glu::TYPE_FLOAT_VEC2);
274 typeCandidates.push_back(glu::TYPE_FLOAT_VEC3);
275 typeCandidates.push_back(glu::TYPE_FLOAT_VEC4);
276 typeCandidates.push_back(glu::TYPE_INT_VEC2);
277 typeCandidates.push_back(glu::TYPE_INT_VEC3);
278 typeCandidates.push_back(glu::TYPE_INT_VEC4);
279 typeCandidates.push_back(glu::TYPE_UINT_VEC2);
280 typeCandidates.push_back(glu::TYPE_UINT_VEC3);
281 typeCandidates.push_back(glu::TYPE_UINT_VEC4);
282 typeCandidates.push_back(glu::TYPE_BOOL_VEC2);
283 typeCandidates.push_back(glu::TYPE_BOOL_VEC3);
284 typeCandidates.push_back(glu::TYPE_BOOL_VEC4);
285 }
286
287 if (m_features & FEATURE_MATRICES)
288 {
289 typeCandidates.push_back(glu::TYPE_FLOAT_MAT2);
290 typeCandidates.push_back(glu::TYPE_FLOAT_MAT2X3);
291 typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X2);
292 typeCandidates.push_back(glu::TYPE_FLOAT_MAT3);
293 typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X4);
294 typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X2);
295 typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X3);
296 typeCandidates.push_back(glu::TYPE_FLOAT_MAT4);
297 }
298
299 glu::DataType type = rnd.choose<glu::DataType>(typeCandidates.begin(), typeCandidates.end());
300 glu::Precision precision;
301
302 if (!glu::isDataTypeBoolOrBVec(type))
303 {
304 // Precision.
305 static const glu::Precision precisionCandidates[] = {glu::PRECISION_LOWP, glu::PRECISION_MEDIUMP,
306 glu::PRECISION_HIGHP};
307 precision = rnd.choose<glu::Precision>(&precisionCandidates[0],
308 &precisionCandidates[DE_LENGTH_OF_ARRAY(precisionCandidates)]);
309 }
310 else
311 precision = glu::PRECISION_LAST;
312
313 return glu::VarType(type, precision);
314 }
315 }
316
317 class BlockBasicTypeCase : public SSBOLayoutCase
318 {
319 public:
BlockBasicTypeCase(Context & context,const char * name,const char * description,const VarType & type,uint32_t layoutFlags,int numInstances)320 BlockBasicTypeCase(Context &context, const char *name, const char *description, const VarType &type,
321 uint32_t layoutFlags, int numInstances)
322 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
323 glu::GLSL_VERSION_310_ES, BUFFERMODE_PER_BLOCK)
324 {
325 BufferBlock &block = m_interface.allocBlock("Block");
326 block.addMember(BufferVar("var", type, ACCESS_READ | ACCESS_WRITE));
327 block.setFlags(layoutFlags);
328
329 if (numInstances > 0)
330 {
331 block.setArraySize(numInstances);
332 block.setInstanceName("block");
333 }
334 }
335 };
336
337 class BlockBasicUnsizedArrayCase : public SSBOLayoutCase
338 {
339 public:
BlockBasicUnsizedArrayCase(Context & context,const char * name,const char * description,const VarType & elementType,int arraySize,uint32_t layoutFlags)340 BlockBasicUnsizedArrayCase(Context &context, const char *name, const char *description, const VarType &elementType,
341 int arraySize, uint32_t layoutFlags)
342 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
343 glu::GLSL_VERSION_310_ES, BUFFERMODE_PER_BLOCK)
344 {
345 BufferBlock &block = m_interface.allocBlock("Block");
346 block.addMember(BufferVar("var", VarType(elementType, VarType::UNSIZED_ARRAY), ACCESS_READ | ACCESS_WRITE));
347 block.setFlags(layoutFlags);
348
349 block.setLastUnsizedArraySize(0, arraySize);
350 }
351 };
352
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,Context & context,const char * groupName,const char * description,SSBOLayoutCase::BufferMode bufferMode,uint32_t features,int numCases,uint32_t baseSeed)353 static void createRandomCaseGroup(tcu::TestCaseGroup *parentGroup, Context &context, const char *groupName,
354 const char *description, SSBOLayoutCase::BufferMode bufferMode, uint32_t features,
355 int numCases, uint32_t baseSeed)
356 {
357 tcu::TestCaseGroup *group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
358 parentGroup->addChild(group);
359
360 baseSeed += (uint32_t)context.getTestContext().getCommandLine().getBaseSeed();
361
362 for (int ndx = 0; ndx < numCases; ndx++)
363 group->addChild(new RandomSSBOLayoutCase(context, de::toString(ndx).c_str(), "", bufferMode, features,
364 (uint32_t)ndx + baseSeed));
365 }
366
367 class BlockSingleStructCase : public SSBOLayoutCase
368 {
369 public:
BlockSingleStructCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)370 BlockSingleStructCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
371 BufferMode bufferMode, int numInstances)
372 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
373 glu::GLSL_VERSION_310_ES, bufferMode)
374 , m_layoutFlags(layoutFlags)
375 , m_numInstances(numInstances)
376 {
377 }
378
init(void)379 void init(void)
380 {
381 StructType &typeS = m_interface.allocStruct("S");
382 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, glu::PRECISION_HIGHP)); // \todo [pyry] First member is unused.
383 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, glu::PRECISION_MEDIUMP), 4));
384 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
385
386 BufferBlock &block = m_interface.allocBlock("Block");
387 block.addMember(BufferVar("s", VarType(&typeS), ACCESS_READ | ACCESS_WRITE));
388 block.setFlags(m_layoutFlags);
389
390 if (m_numInstances > 0)
391 {
392 block.setInstanceName("block");
393 block.setArraySize(m_numInstances);
394 }
395 }
396
397 private:
398 uint32_t m_layoutFlags;
399 int m_numInstances;
400 };
401
402 class BlockSingleStructArrayCase : public SSBOLayoutCase
403 {
404 public:
BlockSingleStructArrayCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)405 BlockSingleStructArrayCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
406 BufferMode bufferMode, int numInstances)
407 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
408 glu::GLSL_VERSION_310_ES, bufferMode)
409 , m_layoutFlags(layoutFlags)
410 , m_numInstances(numInstances)
411 {
412 }
413
init(void)414 void init(void)
415 {
416 StructType &typeS = m_interface.allocStruct("S");
417 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, glu::PRECISION_HIGHP)); // \todo [pyry] UNUSED
418 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, glu::PRECISION_MEDIUMP), 4));
419 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
420
421 BufferBlock &block = m_interface.allocBlock("Block");
422 block.addMember(BufferVar("u", VarType(glu::TYPE_UINT, glu::PRECISION_LOWP), 0 /* no access */));
423 block.addMember(BufferVar("s", VarType(VarType(&typeS), 3), ACCESS_READ | ACCESS_WRITE));
424 block.addMember(BufferVar("v", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_MEDIUMP), ACCESS_WRITE));
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 uint32_t m_layoutFlags;
436 int m_numInstances;
437 };
438
439 class BlockSingleNestedStructCase : public SSBOLayoutCase
440 {
441 public:
BlockSingleNestedStructCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)442 BlockSingleNestedStructCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
443 BufferMode bufferMode, int numInstances)
444 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
445 glu::GLSL_VERSION_310_ES, bufferMode)
446 , m_layoutFlags(layoutFlags)
447 , m_numInstances(numInstances)
448 {
449 }
450
init(void)451 void init(void)
452 {
453 StructType &typeS = m_interface.allocStruct("S");
454 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, glu::PRECISION_HIGHP));
455 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, glu::PRECISION_MEDIUMP), 4));
456 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)); // \todo [pyry] UNUSED
457
458 StructType &typeT = m_interface.allocStruct("T");
459 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, glu::PRECISION_MEDIUMP));
460 typeT.addMember("b", VarType(&typeS));
461
462 BufferBlock &block = m_interface.allocBlock("Block");
463 block.addMember(BufferVar("s", VarType(&typeS), ACCESS_READ));
464 block.addMember(BufferVar("v", VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_LOWP), 0 /* no access */));
465 block.addMember(BufferVar("t", VarType(&typeT), ACCESS_READ | ACCESS_WRITE));
466 block.addMember(BufferVar("u", VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP), ACCESS_WRITE));
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 uint32_t m_layoutFlags;
478 int m_numInstances;
479 };
480
481 class BlockSingleNestedStructArrayCase : public SSBOLayoutCase
482 {
483 public:
BlockSingleNestedStructArrayCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)484 BlockSingleNestedStructArrayCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
485 BufferMode bufferMode, int numInstances)
486 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
487 glu::GLSL_VERSION_310_ES, bufferMode)
488 , m_layoutFlags(layoutFlags)
489 , m_numInstances(numInstances)
490 {
491 }
492
init(void)493 void init(void)
494 {
495 StructType &typeS = m_interface.allocStruct("S");
496 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, glu::PRECISION_HIGHP));
497 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, glu::PRECISION_MEDIUMP), 4));
498 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)); // \todo [pyry] UNUSED
499
500 StructType &typeT = m_interface.allocStruct("T");
501 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, glu::PRECISION_MEDIUMP));
502 typeT.addMember("b", VarType(VarType(&typeS), 3));
503
504 BufferBlock &block = m_interface.allocBlock("Block");
505 block.addMember(BufferVar("s", VarType(&typeS), ACCESS_WRITE));
506 block.addMember(BufferVar("v", VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_LOWP), 0 /* no access */));
507 block.addMember(BufferVar("t", VarType(VarType(&typeT), 2), ACCESS_READ));
508 block.addMember(BufferVar("u", VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP), ACCESS_READ | ACCESS_WRITE));
509 block.setFlags(m_layoutFlags);
510
511 if (m_numInstances > 0)
512 {
513 block.setInstanceName("block");
514 block.setArraySize(m_numInstances);
515 }
516 }
517
518 private:
519 uint32_t m_layoutFlags;
520 int m_numInstances;
521 };
522
523 class BlockUnsizedStructArrayCase : public SSBOLayoutCase
524 {
525 public:
BlockUnsizedStructArrayCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)526 BlockUnsizedStructArrayCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
527 BufferMode bufferMode, int numInstances)
528 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
529 glu::GLSL_VERSION_310_ES, bufferMode)
530 , m_layoutFlags(layoutFlags)
531 , m_numInstances(numInstances)
532 {
533 }
534
init(void)535 void init(void)
536 {
537 StructType &typeS = m_interface.allocStruct("S");
538 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC2, glu::PRECISION_HIGHP)); // \todo [pyry] UNUSED
539 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2X4, glu::PRECISION_MEDIUMP), 4));
540 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC3, glu::PRECISION_HIGHP));
541
542 BufferBlock &block = m_interface.allocBlock("Block");
543 block.addMember(BufferVar("u", VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_LOWP), 0 /* no access */));
544 block.addMember(BufferVar("v", VarType(glu::TYPE_UINT, glu::PRECISION_MEDIUMP), ACCESS_WRITE));
545 block.addMember(BufferVar("s", VarType(VarType(&typeS), VarType::UNSIZED_ARRAY), ACCESS_READ | ACCESS_WRITE));
546 block.setFlags(m_layoutFlags);
547
548 if (m_numInstances > 0)
549 {
550 block.setInstanceName("block");
551 block.setArraySize(m_numInstances);
552 }
553
554 {
555 de::Random rnd(246);
556 for (int ndx = 0; ndx < (m_numInstances ? m_numInstances : 1); ndx++)
557 {
558 const int lastArrayLen = rnd.getInt(1, 5);
559 block.setLastUnsizedArraySize(ndx, lastArrayLen);
560 }
561 }
562 }
563
564 private:
565 uint32_t m_layoutFlags;
566 int m_numInstances;
567 };
568
569 class Block2LevelUnsizedStructArrayCase : public SSBOLayoutCase
570 {
571 public:
Block2LevelUnsizedStructArrayCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)572 Block2LevelUnsizedStructArrayCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
573 BufferMode bufferMode, int numInstances)
574 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
575 glu::GLSL_VERSION_310_ES, bufferMode)
576 , m_layoutFlags(layoutFlags)
577 , m_numInstances(numInstances)
578 {
579 }
580
init(void)581 void init(void)
582 {
583 StructType &typeS = m_interface.allocStruct("S");
584 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, glu::PRECISION_HIGHP));
585 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
586
587 BufferBlock &block = m_interface.allocBlock("Block");
588 block.addMember(BufferVar("u", VarType(glu::TYPE_UINT, glu::PRECISION_LOWP), 0 /* no access */));
589 block.addMember(BufferVar("v", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_MEDIUMP), ACCESS_WRITE));
590 block.addMember(
591 BufferVar("s", VarType(VarType(VarType(&typeS), 2), VarType::UNSIZED_ARRAY), ACCESS_READ | ACCESS_WRITE));
592 block.setFlags(m_layoutFlags);
593
594 if (m_numInstances > 0)
595 {
596 block.setInstanceName("block");
597 block.setArraySize(m_numInstances);
598 }
599
600 {
601 de::Random rnd(2344);
602 for (int ndx = 0; ndx < (m_numInstances ? m_numInstances : 1); ndx++)
603 {
604 const int lastArrayLen = rnd.getInt(1, 5);
605 block.setLastUnsizedArraySize(ndx, lastArrayLen);
606 }
607 }
608 }
609
610 private:
611 uint32_t m_layoutFlags;
612 int m_numInstances;
613 };
614
615 class BlockUnsizedNestedStructArrayCase : public SSBOLayoutCase
616 {
617 public:
BlockUnsizedNestedStructArrayCase(Context & context,const char * name,const char * description,uint32_t layoutFlags,BufferMode bufferMode,int numInstances)618 BlockUnsizedNestedStructArrayCase(Context &context, const char *name, const char *description, uint32_t layoutFlags,
619 BufferMode bufferMode, int numInstances)
620 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
621 glu::GLSL_VERSION_310_ES, bufferMode)
622 , m_layoutFlags(layoutFlags)
623 , m_numInstances(numInstances)
624 {
625 }
626
init(void)627 void init(void)
628 {
629 StructType &typeS = m_interface.allocStruct("S");
630 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, glu::PRECISION_HIGHP));
631 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_MEDIUMP), 4));
632 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)); // \todo [pyry] UNUSED
633
634 StructType &typeT = m_interface.allocStruct("T");
635 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT4X3, glu::PRECISION_MEDIUMP));
636 typeT.addMember("b", VarType(VarType(&typeS), 3));
637 typeT.addMember("c", VarType(glu::TYPE_INT, glu::PRECISION_HIGHP));
638
639 BufferBlock &block = m_interface.allocBlock("Block");
640 block.addMember(BufferVar("s", VarType(&typeS), ACCESS_WRITE));
641 block.addMember(BufferVar("v", VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_LOWP), 0 /* no access */));
642 block.addMember(BufferVar("u", VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP), ACCESS_READ | ACCESS_WRITE));
643 block.addMember(BufferVar("t", VarType(VarType(&typeT), VarType::UNSIZED_ARRAY), ACCESS_READ));
644 block.setFlags(m_layoutFlags);
645
646 if (m_numInstances > 0)
647 {
648 block.setInstanceName("block");
649 block.setArraySize(m_numInstances);
650 }
651
652 {
653 de::Random rnd(7921);
654 for (int ndx = 0; ndx < (m_numInstances ? m_numInstances : 1); ndx++)
655 {
656 const int lastArrayLen = rnd.getInt(1, 5);
657 block.setLastUnsizedArraySize(ndx, lastArrayLen);
658 }
659 }
660 }
661
662 private:
663 uint32_t m_layoutFlags;
664 int m_numInstances;
665 };
666
667 class BlockMultiBasicTypesCase : public SSBOLayoutCase
668 {
669 public:
BlockMultiBasicTypesCase(Context & context,const char * name,const char * description,uint32_t flagsA,uint32_t flagsB,BufferMode bufferMode,int numInstances)670 BlockMultiBasicTypesCase(Context &context, const char *name, const char *description, uint32_t flagsA,
671 uint32_t flagsB, BufferMode bufferMode, int numInstances)
672 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
673 glu::GLSL_VERSION_310_ES, bufferMode)
674 , m_flagsA(flagsA)
675 , m_flagsB(flagsB)
676 , m_numInstances(numInstances)
677 {
678 }
679
init(void)680 void init(void)
681 {
682 BufferBlock &blockA = m_interface.allocBlock("BlockA");
683 blockA.addMember(BufferVar("a", VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), ACCESS_READ | ACCESS_WRITE));
684 blockA.addMember(BufferVar("b", VarType(glu::TYPE_UINT_VEC3, glu::PRECISION_LOWP), 0 /* no access */));
685 blockA.addMember(BufferVar("c", VarType(glu::TYPE_FLOAT_MAT2, glu::PRECISION_MEDIUMP), ACCESS_READ));
686 blockA.setInstanceName("blockA");
687 blockA.setFlags(m_flagsA);
688
689 BufferBlock &blockB = m_interface.allocBlock("BlockB");
690 blockB.addMember(BufferVar("a", VarType(glu::TYPE_FLOAT_MAT3, glu::PRECISION_MEDIUMP), ACCESS_WRITE));
691 blockB.addMember(BufferVar("b", VarType(glu::TYPE_INT_VEC2, glu::PRECISION_LOWP), ACCESS_READ));
692 blockB.addMember(BufferVar("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), 0 /* no access */));
693 blockB.addMember(BufferVar("d", VarType(glu::TYPE_BOOL, glu::PRECISION_LAST), ACCESS_READ | ACCESS_WRITE));
694 blockB.setInstanceName("blockB");
695 blockB.setFlags(m_flagsB);
696
697 if (m_numInstances > 0)
698 {
699 blockA.setArraySize(m_numInstances);
700 blockB.setArraySize(m_numInstances);
701 }
702 }
703
704 private:
705 uint32_t m_flagsA;
706 uint32_t m_flagsB;
707 int m_numInstances;
708 };
709
710 class BlockMultiNestedStructCase : public SSBOLayoutCase
711 {
712 public:
BlockMultiNestedStructCase(Context & context,const char * name,const char * description,uint32_t flagsA,uint32_t flagsB,BufferMode bufferMode,int numInstances)713 BlockMultiNestedStructCase(Context &context, const char *name, const char *description, uint32_t flagsA,
714 uint32_t flagsB, BufferMode bufferMode, int numInstances)
715 : SSBOLayoutCase(context.getTestContext(), context.getRenderContext(), name, description,
716 glu::GLSL_VERSION_310_ES, bufferMode)
717 , m_flagsA(flagsA)
718 , m_flagsB(flagsB)
719 , m_numInstances(numInstances)
720 {
721 }
722
init(void)723 void init(void)
724 {
725 StructType &typeS = m_interface.allocStruct("S");
726 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, glu::PRECISION_LOWP));
727 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, glu::PRECISION_MEDIUMP), 4));
728 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
729
730 StructType &typeT = m_interface.allocStruct("T");
731 typeT.addMember("a", VarType(glu::TYPE_UINT, glu::PRECISION_MEDIUMP)); // \todo [pyry] UNUSED
732 typeT.addMember("b", VarType(&typeS));
733 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, glu::PRECISION_LAST));
734
735 BufferBlock &blockA = m_interface.allocBlock("BlockA");
736 blockA.addMember(BufferVar("a", VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), ACCESS_READ | ACCESS_WRITE));
737 blockA.addMember(BufferVar("b", VarType(&typeS), ACCESS_WRITE));
738 blockA.addMember(BufferVar("c", VarType(glu::TYPE_UINT_VEC3, glu::PRECISION_LOWP), 0 /* no access */));
739 blockA.setInstanceName("blockA");
740 blockA.setFlags(m_flagsA);
741
742 BufferBlock &blockB = m_interface.allocBlock("BlockB");
743 blockB.addMember(BufferVar("a", VarType(glu::TYPE_FLOAT_MAT2, glu::PRECISION_MEDIUMP), ACCESS_WRITE));
744 blockB.addMember(BufferVar("b", VarType(&typeT), ACCESS_READ | ACCESS_WRITE));
745 blockB.addMember(BufferVar("c", VarType(glu::TYPE_BOOL_VEC4, glu::PRECISION_LAST), 0 /* no access */));
746 blockB.addMember(BufferVar("d", VarType(glu::TYPE_BOOL, glu::PRECISION_LAST), ACCESS_READ | ACCESS_WRITE));
747 blockB.setInstanceName("blockB");
748 blockB.setFlags(m_flagsB);
749
750 if (m_numInstances > 0)
751 {
752 blockA.setArraySize(m_numInstances);
753 blockB.setArraySize(m_numInstances);
754 }
755 }
756
757 private:
758 uint32_t m_flagsA;
759 uint32_t m_flagsB;
760 int m_numInstances;
761 };
762
763 } // namespace
764
SSBOLayoutTests(Context & context)765 SSBOLayoutTests::SSBOLayoutTests(Context &context) : TestCaseGroup(context, "layout", "SSBO Layout Tests")
766 {
767 }
768
~SSBOLayoutTests(void)769 SSBOLayoutTests::~SSBOLayoutTests(void)
770 {
771 }
772
init(void)773 void SSBOLayoutTests::init(void)
774 {
775 static const glu::DataType basicTypes[] = {
776 glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT_VEC4,
777 glu::TYPE_INT, glu::TYPE_INT_VEC2, glu::TYPE_INT_VEC3, glu::TYPE_INT_VEC4,
778 glu::TYPE_UINT, glu::TYPE_UINT_VEC2, glu::TYPE_UINT_VEC3, glu::TYPE_UINT_VEC4,
779 glu::TYPE_BOOL, glu::TYPE_BOOL_VEC2, glu::TYPE_BOOL_VEC3, glu::TYPE_BOOL_VEC4,
780 glu::TYPE_FLOAT_MAT2, glu::TYPE_FLOAT_MAT3, glu::TYPE_FLOAT_MAT4, glu::TYPE_FLOAT_MAT2X3,
781 glu::TYPE_FLOAT_MAT2X4, glu::TYPE_FLOAT_MAT3X2, glu::TYPE_FLOAT_MAT3X4, glu::TYPE_FLOAT_MAT4X2,
782 glu::TYPE_FLOAT_MAT4X3};
783
784 static const struct
785 {
786 const char *name;
787 uint32_t flags;
788 } layoutFlags[] = {
789 {"shared", LAYOUT_SHARED}, {"packed", LAYOUT_PACKED}, {"std140", LAYOUT_STD140}, {"std430", LAYOUT_STD430}};
790
791 static const struct
792 {
793 const char *name;
794 uint32_t flags;
795 } matrixFlags[] = {{"row_major", LAYOUT_ROW_MAJOR}, {"column_major", LAYOUT_COLUMN_MAJOR}};
796
797 static const struct
798 {
799 const char *name;
800 SSBOLayoutCase::BufferMode mode;
801 } bufferModes[] = {{"per_block_buffer", SSBOLayoutCase::BUFFERMODE_PER_BLOCK},
802 {"single_buffer", SSBOLayoutCase::BUFFERMODE_SINGLE}};
803
804 // ubo.single_basic_type
805 {
806 tcu::TestCaseGroup *singleBasicTypeGroup =
807 new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
808 addChild(singleBasicTypeGroup);
809
810 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
811 {
812 tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
813 singleBasicTypeGroup->addChild(layoutGroup);
814
815 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
816 {
817 glu::DataType type = basicTypes[basicTypeNdx];
818 const char *typeName = glu::getDataTypeName(type);
819
820 if (glu::isDataTypeBoolOrBVec(type))
821 layoutGroup->addChild(new BlockBasicTypeCase(m_context, typeName, "",
822 VarType(type, glu::PRECISION_LAST),
823 layoutFlags[layoutFlagNdx].flags, 0));
824 else
825 {
826 for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
827 {
828 const glu::Precision precision = glu::Precision(precNdx);
829 const string caseName = string(glu::getPrecisionName(precision)) + "_" + typeName;
830
831 layoutGroup->addChild(new BlockBasicTypeCase(m_context, caseName.c_str(), "",
832 VarType(type, precision),
833 layoutFlags[layoutFlagNdx].flags, 0));
834 }
835 }
836
837 if (glu::isDataTypeMatrix(type))
838 {
839 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
840 {
841 for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
842 {
843 const glu::Precision precision = glu::Precision(precNdx);
844 const string caseName = string(matrixFlags[matFlagNdx].name) + "_" +
845 string(glu::getPrecisionName(precision)) + "_" + typeName;
846
847 layoutGroup->addChild(new BlockBasicTypeCase(
848 m_context, caseName.c_str(), "", glu::VarType(type, precision),
849 layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags, 0));
850 }
851 }
852 }
853 }
854 }
855 }
856
857 // ubo.single_basic_array
858 {
859 tcu::TestCaseGroup *singleBasicArrayGroup =
860 new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
861 addChild(singleBasicArrayGroup);
862
863 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
864 {
865 tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
866 singleBasicArrayGroup->addChild(layoutGroup);
867
868 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
869 {
870 glu::DataType type = basicTypes[basicTypeNdx];
871 const char *typeName = glu::getDataTypeName(type);
872 const int arraySize = 3;
873
874 layoutGroup->addChild(new BlockBasicTypeCase(
875 m_context, typeName, "",
876 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_HIGHP),
877 arraySize),
878 layoutFlags[layoutFlagNdx].flags, 0));
879
880 if (glu::isDataTypeMatrix(type))
881 {
882 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
883 layoutGroup->addChild(new BlockBasicTypeCase(
884 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "",
885 VarType(VarType(type, glu::PRECISION_HIGHP), arraySize),
886 layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags, 0));
887 }
888 }
889 }
890 }
891
892 // ubo.basic_unsized_array
893 {
894 tcu::TestCaseGroup *basicUnsizedArray =
895 new tcu::TestCaseGroup(m_testCtx, "basic_unsized_array", "Basic unsized array tests");
896 addChild(basicUnsizedArray);
897
898 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
899 {
900 tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
901 basicUnsizedArray->addChild(layoutGroup);
902
903 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
904 {
905 glu::DataType type = basicTypes[basicTypeNdx];
906 const char *typeName = glu::getDataTypeName(type);
907 const int arraySize = 19;
908
909 layoutGroup->addChild(new BlockBasicUnsizedArrayCase(
910 m_context, typeName, "",
911 VarType(type, glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_HIGHP),
912 arraySize, layoutFlags[layoutFlagNdx].flags));
913
914 if (glu::isDataTypeMatrix(type))
915 {
916 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
917 layoutGroup->addChild(new BlockBasicUnsizedArrayCase(
918 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "",
919 VarType(type, glu::PRECISION_HIGHP), arraySize,
920 layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags));
921 }
922 }
923 }
924 }
925
926 // ubo.2_level_array
927 {
928 tcu::TestCaseGroup *nestedArrayGroup =
929 new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level nested array");
930 addChild(nestedArrayGroup);
931
932 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
933 {
934 tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
935 nestedArrayGroup->addChild(layoutGroup);
936
937 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
938 {
939 glu::DataType type = basicTypes[basicTypeNdx];
940 const char *typeName = glu::getDataTypeName(type);
941 const int childSize = 3;
942 const int parentSize = 4;
943 const VarType childType(
944 VarType(type, glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_HIGHP),
945 childSize);
946 const VarType fullType(childType, parentSize);
947
948 layoutGroup->addChild(
949 new BlockBasicTypeCase(m_context, typeName, "", fullType, layoutFlags[layoutFlagNdx].flags, 0));
950
951 if (glu::isDataTypeMatrix(type))
952 {
953 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
954 layoutGroup->addChild(new BlockBasicTypeCase(
955 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "", fullType,
956 layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags, 0));
957 }
958 }
959 }
960 }
961
962 // ubo.3_level_array
963 {
964 tcu::TestCaseGroup *nestedArrayGroup =
965 new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level nested array");
966 addChild(nestedArrayGroup);
967
968 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
969 {
970 tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
971 nestedArrayGroup->addChild(layoutGroup);
972
973 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
974 {
975 glu::DataType type = basicTypes[basicTypeNdx];
976 const char *typeName = glu::getDataTypeName(type);
977 const int childSize0 = 3;
978 const int childSize1 = 2;
979 const int parentSize = 4;
980 const VarType childType0(
981 VarType(type, glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_HIGHP),
982 childSize0);
983 const VarType childType1(childType0, childSize1);
984 const VarType fullType(childType1, parentSize);
985
986 layoutGroup->addChild(
987 new BlockBasicTypeCase(m_context, typeName, "", fullType, layoutFlags[layoutFlagNdx].flags, 0));
988
989 if (glu::isDataTypeMatrix(type))
990 {
991 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
992 layoutGroup->addChild(new BlockBasicTypeCase(
993 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "", fullType,
994 layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags, 0));
995 }
996 }
997 }
998 }
999
1000 // ubo.3_level_unsized_array
1001 {
1002 tcu::TestCaseGroup *nestedArrayGroup =
1003 new tcu::TestCaseGroup(m_testCtx, "3_level_unsized_array", "3-level nested array, top-level array unsized");
1004 addChild(nestedArrayGroup);
1005
1006 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1007 {
1008 tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
1009 nestedArrayGroup->addChild(layoutGroup);
1010
1011 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
1012 {
1013 glu::DataType type = basicTypes[basicTypeNdx];
1014 const char *typeName = glu::getDataTypeName(type);
1015 const int childSize0 = 2;
1016 const int childSize1 = 4;
1017 const int parentSize = 3;
1018 const VarType childType0(
1019 VarType(type, glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_HIGHP),
1020 childSize0);
1021 const VarType childType1(childType0, childSize1);
1022
1023 layoutGroup->addChild(new BlockBasicUnsizedArrayCase(m_context, typeName, "", childType1, parentSize,
1024 layoutFlags[layoutFlagNdx].flags));
1025
1026 if (glu::isDataTypeMatrix(type))
1027 {
1028 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
1029 layoutGroup->addChild(new BlockBasicUnsizedArrayCase(
1030 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "", childType1,
1031 parentSize, layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags));
1032 }
1033 }
1034 }
1035 }
1036
1037 // ubo.single_struct
1038 {
1039 tcu::TestCaseGroup *singleStructGroup =
1040 new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
1041 addChild(singleStructGroup);
1042
1043 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1044 {
1045 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1046 singleStructGroup->addChild(modeGroup);
1047
1048 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1049 {
1050 for (int isArray = 0; isArray < 2; isArray++)
1051 {
1052 const uint32_t caseFlags = layoutFlags[layoutFlagNdx].flags;
1053 string caseName = layoutFlags[layoutFlagNdx].name;
1054
1055 if (bufferModes[modeNdx].mode == SSBOLayoutCase::BUFFERMODE_SINGLE && isArray == 0)
1056 continue; // Doesn't make sense to add this variant.
1057
1058 if (isArray)
1059 caseName += "_instance_array";
1060
1061 modeGroup->addChild(new BlockSingleStructCase(m_context, caseName.c_str(), "", caseFlags,
1062 bufferModes[modeNdx].mode, isArray ? 3 : 0));
1063 }
1064 }
1065 }
1066 }
1067
1068 // ubo.single_struct_array
1069 {
1070 tcu::TestCaseGroup *singleStructArrayGroup =
1071 new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
1072 addChild(singleStructArrayGroup);
1073
1074 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1075 {
1076 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1077 singleStructArrayGroup->addChild(modeGroup);
1078
1079 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1080 {
1081 for (int isArray = 0; isArray < 2; isArray++)
1082 {
1083 std::string baseName = layoutFlags[layoutFlagNdx].name;
1084 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1085
1086 if (bufferModes[modeNdx].mode == SSBOLayoutCase::BUFFERMODE_SINGLE && isArray == 0)
1087 continue; // Doesn't make sense to add this variant.
1088
1089 if (isArray)
1090 baseName += "_instance_array";
1091
1092 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, baseName.c_str(), "", baseFlags,
1093 bufferModes[modeNdx].mode, isArray ? 3 : 0));
1094 }
1095 }
1096 }
1097 }
1098
1099 // ubo.single_nested_struct
1100 {
1101 tcu::TestCaseGroup *singleNestedStructGroup =
1102 new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
1103 addChild(singleNestedStructGroup);
1104
1105 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1106 {
1107 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1108 singleNestedStructGroup->addChild(modeGroup);
1109
1110 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1111 {
1112 for (int isArray = 0; isArray < 2; isArray++)
1113 {
1114 std::string baseName = layoutFlags[layoutFlagNdx].name;
1115 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1116
1117 if (bufferModes[modeNdx].mode == SSBOLayoutCase::BUFFERMODE_SINGLE && isArray == 0)
1118 continue; // Doesn't make sense to add this variant.
1119
1120 if (isArray)
1121 baseName += "_instance_array";
1122
1123 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, baseName.c_str(), "", baseFlags,
1124 bufferModes[modeNdx].mode, isArray ? 3 : 0));
1125 }
1126 }
1127 }
1128 }
1129
1130 // ubo.single_nested_struct_array
1131 {
1132 tcu::TestCaseGroup *singleNestedStructArrayGroup =
1133 new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
1134 addChild(singleNestedStructArrayGroup);
1135
1136 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1137 {
1138 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1139 singleNestedStructArrayGroup->addChild(modeGroup);
1140
1141 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1142 {
1143 for (int isArray = 0; isArray < 2; isArray++)
1144 {
1145 std::string baseName = layoutFlags[layoutFlagNdx].name;
1146 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1147
1148 if (bufferModes[modeNdx].mode == SSBOLayoutCase::BUFFERMODE_SINGLE && isArray == 0)
1149 continue; // Doesn't make sense to add this variant.
1150
1151 if (isArray)
1152 baseName += "_instance_array";
1153
1154 modeGroup->addChild(new BlockSingleNestedStructArrayCase(
1155 m_context, baseName.c_str(), "", baseFlags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1156 }
1157 }
1158 }
1159 }
1160
1161 // ubo.unsized_struct_array
1162 {
1163 tcu::TestCaseGroup *singleStructArrayGroup =
1164 new tcu::TestCaseGroup(m_testCtx, "unsized_struct_array", "Unsized struct array in one uniform block");
1165 addChild(singleStructArrayGroup);
1166
1167 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1168 {
1169 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1170 singleStructArrayGroup->addChild(modeGroup);
1171
1172 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1173 {
1174 for (int isArray = 0; isArray < 2; isArray++)
1175 {
1176 std::string baseName = layoutFlags[layoutFlagNdx].name;
1177 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1178
1179 if (bufferModes[modeNdx].mode == SSBOLayoutCase::BUFFERMODE_SINGLE && isArray == 0)
1180 continue; // Doesn't make sense to add this variant.
1181
1182 if (isArray)
1183 baseName += "_instance_array";
1184
1185 modeGroup->addChild(new BlockUnsizedStructArrayCase(m_context, baseName.c_str(), "", baseFlags,
1186 bufferModes[modeNdx].mode, isArray ? 3 : 0));
1187 }
1188 }
1189 }
1190 }
1191
1192 // ubo.2_level_unsized_struct_array
1193 {
1194 tcu::TestCaseGroup *structArrayGroup = new tcu::TestCaseGroup(
1195 m_testCtx, "2_level_unsized_struct_array", "Unsized 2-level struct array in one uniform block");
1196 addChild(structArrayGroup);
1197
1198 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1199 {
1200 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1201 structArrayGroup->addChild(modeGroup);
1202
1203 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1204 {
1205 for (int isArray = 0; isArray < 2; isArray++)
1206 {
1207 std::string baseName = layoutFlags[layoutFlagNdx].name;
1208 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1209
1210 if (bufferModes[modeNdx].mode == SSBOLayoutCase::BUFFERMODE_SINGLE && isArray == 0)
1211 continue; // Doesn't make sense to add this variant.
1212
1213 if (isArray)
1214 baseName += "_instance_array";
1215
1216 modeGroup->addChild(new Block2LevelUnsizedStructArrayCase(
1217 m_context, baseName.c_str(), "", baseFlags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1218 }
1219 }
1220 }
1221 }
1222
1223 // ubo.unsized_nested_struct_array
1224 {
1225 tcu::TestCaseGroup *singleNestedStructArrayGroup = new tcu::TestCaseGroup(
1226 m_testCtx, "unsized_nested_struct_array", "Unsized, nested struct array in one uniform block");
1227 addChild(singleNestedStructArrayGroup);
1228
1229 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1230 {
1231 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1232 singleNestedStructArrayGroup->addChild(modeGroup);
1233
1234 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1235 {
1236 for (int isArray = 0; isArray < 2; isArray++)
1237 {
1238 std::string baseName = layoutFlags[layoutFlagNdx].name;
1239 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1240
1241 if (bufferModes[modeNdx].mode == SSBOLayoutCase::BUFFERMODE_SINGLE && isArray == 0)
1242 continue; // Doesn't make sense to add this variant.
1243
1244 if (isArray)
1245 baseName += "_instance_array";
1246
1247 modeGroup->addChild(new BlockUnsizedNestedStructArrayCase(
1248 m_context, baseName.c_str(), "", baseFlags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1249 }
1250 }
1251 }
1252 }
1253
1254 // ubo.instance_array_basic_type
1255 {
1256 tcu::TestCaseGroup *instanceArrayBasicTypeGroup =
1257 new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
1258 addChild(instanceArrayBasicTypeGroup);
1259
1260 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1261 {
1262 tcu::TestCaseGroup *layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
1263 instanceArrayBasicTypeGroup->addChild(layoutGroup);
1264
1265 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
1266 {
1267 glu::DataType type = basicTypes[basicTypeNdx];
1268 const char *typeName = glu::getDataTypeName(type);
1269 const int numInstances = 3;
1270
1271 layoutGroup->addChild(new BlockBasicTypeCase(
1272 m_context, typeName, "",
1273 VarType(type, glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_HIGHP),
1274 layoutFlags[layoutFlagNdx].flags, numInstances));
1275
1276 if (glu::isDataTypeMatrix(type))
1277 {
1278 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
1279 layoutGroup->addChild(new BlockBasicTypeCase(
1280 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "",
1281 VarType(type, glu::PRECISION_HIGHP),
1282 layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags, numInstances));
1283 }
1284 }
1285 }
1286 }
1287
1288 // ubo.multi_basic_types
1289 {
1290 tcu::TestCaseGroup *multiBasicTypesGroup =
1291 new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
1292 addChild(multiBasicTypesGroup);
1293
1294 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1295 {
1296 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1297 multiBasicTypesGroup->addChild(modeGroup);
1298
1299 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1300 {
1301 for (int isArray = 0; isArray < 2; isArray++)
1302 {
1303 std::string baseName = layoutFlags[layoutFlagNdx].name;
1304 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1305
1306 if (isArray)
1307 baseName += "_instance_array";
1308
1309 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, baseName.c_str(), "", baseFlags,
1310 baseFlags, bufferModes[modeNdx].mode,
1311 isArray ? 3 : 0));
1312 }
1313 }
1314 }
1315 }
1316
1317 // ubo.multi_nested_struct
1318 {
1319 tcu::TestCaseGroup *multiNestedStructGroup =
1320 new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
1321 addChild(multiNestedStructGroup);
1322
1323 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1324 {
1325 tcu::TestCaseGroup *modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1326 multiNestedStructGroup->addChild(modeGroup);
1327
1328 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1329 {
1330 for (int isArray = 0; isArray < 2; isArray++)
1331 {
1332 std::string baseName = layoutFlags[layoutFlagNdx].name;
1333 uint32_t baseFlags = layoutFlags[layoutFlagNdx].flags;
1334
1335 if (isArray)
1336 baseName += "_instance_array";
1337
1338 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, baseName.c_str(), "", baseFlags,
1339 baseFlags, bufferModes[modeNdx].mode,
1340 isArray ? 3 : 0));
1341 }
1342 }
1343 }
1344 }
1345
1346 // ubo.random
1347 {
1348 const uint32_t allLayouts = FEATURE_PACKED_LAYOUT | FEATURE_SHARED_LAYOUT | FEATURE_STD140_LAYOUT;
1349 const uint32_t allBasicTypes = FEATURE_VECTORS | FEATURE_MATRICES;
1350 const uint32_t unused = FEATURE_UNUSED_MEMBERS | FEATURE_UNUSED_VARS;
1351 const uint32_t unsized = FEATURE_UNSIZED_ARRAYS;
1352 const uint32_t matFlags = FEATURE_MATRIX_LAYOUT;
1353
1354 tcu::TestCaseGroup *randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
1355 addChild(randomGroup);
1356
1357 // Basic types.
1358 createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers",
1359 SSBOLayoutCase::BUFFERMODE_PER_BLOCK, allLayouts | unused, 25, 0);
1360 createRandomCaseGroup(randomGroup, m_context, "vector_types", "Scalar and vector types only, per-block buffers",
1361 SSBOLayoutCase::BUFFERMODE_PER_BLOCK, allLayouts | unused | FEATURE_VECTORS, 25, 25);
1362 createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers",
1363 SSBOLayoutCase::BUFFERMODE_PER_BLOCK, allLayouts | unused | allBasicTypes | matFlags, 25,
1364 50);
1365 createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers",
1366 SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1367 allLayouts | unused | allBasicTypes | matFlags | FEATURE_ARRAYS, 25, 50);
1368 createRandomCaseGroup(randomGroup, m_context, "unsized_arrays", "Unsized arrays, per-block buffers",
1369 SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1370 allLayouts | unused | allBasicTypes | matFlags | unsized | FEATURE_ARRAYS, 25, 50);
1371 createRandomCaseGroup(randomGroup, m_context, "arrays_of_arrays", "Arrays of arrays, per-block buffers",
1372 SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1373 allLayouts | unused | allBasicTypes | matFlags | unsized | FEATURE_ARRAYS |
1374 FEATURE_ARRAYS_OF_ARRAYS,
1375 25, 950);
1376
1377 createRandomCaseGroup(randomGroup, m_context, "basic_instance_arrays",
1378 "Basic instance arrays, per-block buffers", SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1379 allLayouts | unused | allBasicTypes | matFlags | unsized | FEATURE_INSTANCE_ARRAYS, 25,
1380 75);
1381 createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers",
1382 SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1383 allLayouts | unused | allBasicTypes | matFlags | unsized | FEATURE_STRUCTS, 25, 100);
1384 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays",
1385 "Nested structs, arrays, per-block buffers", SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1386 allLayouts | unused | allBasicTypes | matFlags | unsized | FEATURE_STRUCTS |
1387 FEATURE_ARRAYS | FEATURE_ARRAYS_OF_ARRAYS,
1388 25, 150);
1389 createRandomCaseGroup(
1390 randomGroup, m_context, "nested_structs_instance_arrays",
1391 "Nested structs, instance arrays, per-block buffers", SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1392 allLayouts | unused | allBasicTypes | matFlags | unsized | FEATURE_STRUCTS | FEATURE_INSTANCE_ARRAYS, 25,
1393 125);
1394 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays",
1395 "Nested structs, instance arrays, per-block buffers",
1396 SSBOLayoutCase::BUFFERMODE_PER_BLOCK,
1397 allLayouts | unused | allBasicTypes | matFlags | unsized | FEATURE_STRUCTS |
1398 FEATURE_ARRAYS | FEATURE_ARRAYS_OF_ARRAYS | FEATURE_INSTANCE_ARRAYS,
1399 25, 175);
1400
1401 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers",
1402 SSBOLayoutCase::BUFFERMODE_PER_BLOCK, ~0u, 50, 200);
1403 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer",
1404 SSBOLayoutCase::BUFFERMODE_SINGLE, ~0u, 50, 250);
1405 }
1406 }
1407
1408 } // namespace Functional
1409 } // namespace gles31
1410 } // namespace deqp
1411