1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Uniform block tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fUniformBlockTests.hpp"
25 #include "glsUniformBlockCase.hpp"
26 #include "glsRandomUniformBlockCase.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "deRandom.hpp"
29 #include "deStringUtil.hpp"
30
31 using std::string;
32 using std::vector;
33
34 namespace deqp
35 {
36 namespace gles3
37 {
38 namespace Functional
39 {
40
41 using gls::UniformBlockCase;
42 using gls::RandomUniformBlockCase;
43 using namespace gls::ub;
44
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,Context & context,const char * groupName,const char * description,UniformBlockCase::BufferMode bufferMode,deUint32 features,int numCases,deUint32 baseSeed)45 static void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, Context& context, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
46 {
47 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
48 parentGroup->addChild(group);
49
50 baseSeed += (deUint32)context.getTestContext().getCommandLine().getBaseSeed();
51
52 for (int ndx = 0; ndx < numCases; ndx++)
53 group->addChild(new RandomUniformBlockCase(context.getTestContext(), context.getRenderContext(), glu::GLSL_VERSION_300_ES,
54 de::toString(ndx).c_str(), "", bufferMode, features, (deUint32)ndx+baseSeed));
55 }
56
57 class BlockBasicTypeCase : public UniformBlockCase
58 {
59 public:
BlockBasicTypeCase(Context & context,const char * name,const char * description,const VarType & type,deUint32 layoutFlags,int numInstances)60 BlockBasicTypeCase (Context& context, const char* name, const char* description, const VarType& type, deUint32 layoutFlags, int numInstances)
61 : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, BUFFERMODE_PER_BLOCK)
62 {
63 UniformBlock& block = m_interface.allocBlock("Block");
64 block.addUniform(Uniform("var", type, 0));
65 block.setFlags(layoutFlags);
66
67 if (numInstances > 0)
68 {
69 block.setArraySize(numInstances);
70 block.setInstanceName("block");
71 }
72 }
73 };
74
createBlockBasicTypeCases(tcu::TestCaseGroup * group,Context & context,const char * name,const VarType & type,deUint32 layoutFlags,int numInstances=0)75 static void createBlockBasicTypeCases (tcu::TestCaseGroup* group, Context& context, const char* name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
76 {
77 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_vertex").c_str(), "", type, layoutFlags|DECLARE_VERTEX, numInstances));
78 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_fragment").c_str(), "", type, layoutFlags|DECLARE_FRAGMENT, numInstances));
79
80 if (!(layoutFlags & LAYOUT_PACKED))
81 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_both").c_str(), "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances));
82 }
83
84 class BlockSingleStructCase : public UniformBlockCase
85 {
86 public:
BlockSingleStructCase(Context & context,const char * name,const char * description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances)87 BlockSingleStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
88 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
89 , m_layoutFlags (layoutFlags)
90 , m_numInstances (numInstances)
91 {
92 }
93
init(void)94 void init (void)
95 {
96 StructType& typeS = m_interface.allocStruct("S");
97 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
98 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
99 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
100
101 UniformBlock& block = m_interface.allocBlock("Block");
102 block.addUniform(Uniform("s", VarType(&typeS), 0));
103 block.setFlags(m_layoutFlags);
104
105 if (m_numInstances > 0)
106 {
107 block.setInstanceName("block");
108 block.setArraySize(m_numInstances);
109 }
110 }
111
112 private:
113 deUint32 m_layoutFlags;
114 int m_numInstances;
115 };
116
117 class BlockSingleStructArrayCase : public UniformBlockCase
118 {
119 public:
BlockSingleStructArrayCase(Context & context,const char * name,const char * description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances)120 BlockSingleStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
121 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
122 , m_layoutFlags (layoutFlags)
123 , m_numInstances (numInstances)
124 {
125 }
126
init(void)127 void init (void)
128 {
129 StructType& typeS = m_interface.allocStruct("S");
130 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
131 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
132 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
133
134 UniformBlock& block = m_interface.allocBlock("Block");
135 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
136 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
137 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
138 block.setFlags(m_layoutFlags);
139
140 if (m_numInstances > 0)
141 {
142 block.setInstanceName("block");
143 block.setArraySize(m_numInstances);
144 }
145 }
146
147 private:
148 deUint32 m_layoutFlags;
149 int m_numInstances;
150 };
151
152 class BlockSingleNestedStructCase : public UniformBlockCase
153 {
154 public:
BlockSingleNestedStructCase(Context & context,const char * name,const char * description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances)155 BlockSingleNestedStructCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
156 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
157 , m_layoutFlags (layoutFlags)
158 , m_numInstances (numInstances)
159 {
160 }
161
init(void)162 void init (void)
163 {
164 StructType& typeS = m_interface.allocStruct("S");
165 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
166 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
167 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
168
169 StructType& typeT = m_interface.allocStruct("T");
170 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
171 typeT.addMember("b", VarType(&typeS));
172
173 UniformBlock& block = m_interface.allocBlock("Block");
174 block.addUniform(Uniform("s", VarType(&typeS), 0));
175 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
176 block.addUniform(Uniform("t", VarType(&typeT), 0));
177 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
178 block.setFlags(m_layoutFlags);
179
180 if (m_numInstances > 0)
181 {
182 block.setInstanceName("block");
183 block.setArraySize(m_numInstances);
184 }
185 }
186
187 private:
188 deUint32 m_layoutFlags;
189 int m_numInstances;
190 };
191
192 class BlockSingleNestedStructArrayCase : public UniformBlockCase
193 {
194 public:
BlockSingleNestedStructArrayCase(Context & context,const char * name,const char * description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances)195 BlockSingleNestedStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
196 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
197 , m_layoutFlags (layoutFlags)
198 , m_numInstances (numInstances)
199 {
200 }
201
init(void)202 void init (void)
203 {
204 StructType& typeS = m_interface.allocStruct("S");
205 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
206 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
207 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
208
209 StructType& typeT = m_interface.allocStruct("T");
210 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
211 typeT.addMember("b", VarType(VarType(&typeS), 3));
212
213 UniformBlock& block = m_interface.allocBlock("Block");
214 block.addUniform(Uniform("s", VarType(&typeS), 0));
215 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
216 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
217 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
218 block.setFlags(m_layoutFlags);
219
220 if (m_numInstances > 0)
221 {
222 block.setInstanceName("block");
223 block.setArraySize(m_numInstances);
224 }
225 }
226
227 private:
228 deUint32 m_layoutFlags;
229 int m_numInstances;
230 };
231
232 class BlockMultiBasicTypesCase : public UniformBlockCase
233 {
234 public:
BlockMultiBasicTypesCase(Context & context,const char * name,const char * description,deUint32 flagsA,deUint32 flagsB,BufferMode bufferMode,int numInstances)235 BlockMultiBasicTypesCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
236 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
237 , m_flagsA (flagsA)
238 , m_flagsB (flagsB)
239 , m_numInstances (numInstances)
240 {
241 }
242
init(void)243 void init (void)
244 {
245 UniformBlock& blockA = m_interface.allocBlock("BlockA");
246 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
247 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
248 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
249 blockA.setInstanceName("blockA");
250 blockA.setFlags(m_flagsA);
251
252 UniformBlock& blockB = m_interface.allocBlock("BlockB");
253 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
254 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
255 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
256 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
257 blockB.setInstanceName("blockB");
258 blockB.setFlags(m_flagsB);
259
260 if (m_numInstances > 0)
261 {
262 blockA.setArraySize(m_numInstances);
263 blockB.setArraySize(m_numInstances);
264 }
265 }
266
267 private:
268 deUint32 m_flagsA;
269 deUint32 m_flagsB;
270 int m_numInstances;
271 };
272
273 class BlockMultiNestedStructCase : public UniformBlockCase
274 {
275 public:
BlockMultiNestedStructCase(Context & context,const char * name,const char * description,deUint32 flagsA,deUint32 flagsB,BufferMode bufferMode,int numInstances)276 BlockMultiNestedStructCase (Context& context, const char* name, const char* description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
277 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_300_ES, bufferMode)
278 , m_flagsA (flagsA)
279 , m_flagsB (flagsB)
280 , m_numInstances (numInstances)
281 {
282 }
283
init(void)284 void init (void)
285 {
286 StructType& typeS = m_interface.allocStruct("S");
287 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
288 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
289 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
290
291 StructType& typeT = m_interface.allocStruct("T");
292 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
293 typeT.addMember("b", VarType(&typeS));
294 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
295
296 UniformBlock& blockA = m_interface.allocBlock("BlockA");
297 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
298 blockA.addUniform(Uniform("b", VarType(&typeS)));
299 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
300 blockA.setInstanceName("blockA");
301 blockA.setFlags(m_flagsA);
302
303 UniformBlock& blockB = m_interface.allocBlock("BlockB");
304 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
305 blockB.addUniform(Uniform("b", VarType(&typeT)));
306 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
307 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
308 blockB.setInstanceName("blockB");
309 blockB.setFlags(m_flagsB);
310
311 if (m_numInstances > 0)
312 {
313 blockA.setArraySize(m_numInstances);
314 blockB.setArraySize(m_numInstances);
315 }
316 }
317
318 private:
319 deUint32 m_flagsA;
320 deUint32 m_flagsB;
321 int m_numInstances;
322 };
323
UniformBlockTests(Context & context)324 UniformBlockTests::UniformBlockTests (Context& context)
325 : TestCaseGroup(context, "ubo", "Uniform Block tests")
326 {
327 }
328
~UniformBlockTests(void)329 UniformBlockTests::~UniformBlockTests (void)
330 {
331 }
332
init(void)333 void UniformBlockTests::init (void)
334 {
335 static const glu::DataType basicTypes[] =
336 {
337 glu::TYPE_FLOAT,
338 glu::TYPE_FLOAT_VEC2,
339 glu::TYPE_FLOAT_VEC3,
340 glu::TYPE_FLOAT_VEC4,
341 glu::TYPE_INT,
342 glu::TYPE_INT_VEC2,
343 glu::TYPE_INT_VEC3,
344 glu::TYPE_INT_VEC4,
345 glu::TYPE_UINT,
346 glu::TYPE_UINT_VEC2,
347 glu::TYPE_UINT_VEC3,
348 glu::TYPE_UINT_VEC4,
349 glu::TYPE_BOOL,
350 glu::TYPE_BOOL_VEC2,
351 glu::TYPE_BOOL_VEC3,
352 glu::TYPE_BOOL_VEC4,
353 glu::TYPE_FLOAT_MAT2,
354 glu::TYPE_FLOAT_MAT3,
355 glu::TYPE_FLOAT_MAT4,
356 glu::TYPE_FLOAT_MAT2X3,
357 glu::TYPE_FLOAT_MAT2X4,
358 glu::TYPE_FLOAT_MAT3X2,
359 glu::TYPE_FLOAT_MAT3X4,
360 glu::TYPE_FLOAT_MAT4X2,
361 glu::TYPE_FLOAT_MAT4X3
362 };
363
364 static const struct
365 {
366 const char* name;
367 deUint32 flags;
368 } precisionFlags[] =
369 {
370 { "lowp", PRECISION_LOW },
371 { "mediump", PRECISION_MEDIUM },
372 { "highp", PRECISION_HIGH }
373 };
374
375 static const struct
376 {
377 const char* name;
378 deUint32 flags;
379 } layoutFlags[] =
380 {
381 { "shared", LAYOUT_SHARED },
382 { "packed", LAYOUT_PACKED },
383 { "std140", LAYOUT_STD140 }
384 };
385
386 static const struct
387 {
388 const char* name;
389 deUint32 flags;
390 } matrixFlags[] =
391 {
392 { "row_major", LAYOUT_ROW_MAJOR },
393 { "column_major", LAYOUT_COLUMN_MAJOR }
394 };
395
396 static const struct
397 {
398 const char* name;
399 UniformBlockCase::BufferMode mode;
400 } bufferModes[] =
401 {
402 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
403 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE }
404 };
405
406 // ubo.single_basic_type
407 {
408 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
409 addChild(singleBasicTypeGroup);
410
411 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
412 {
413 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
414 singleBasicTypeGroup->addChild(layoutGroup);
415
416 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
417 {
418 glu::DataType type = basicTypes[basicTypeNdx];
419 const char* typeName = glu::getDataTypeName(type);
420
421 if (glu::isDataTypeBoolOrBVec(type))
422 createBlockBasicTypeCases(layoutGroup, m_context, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
423 else
424 {
425 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
426 createBlockBasicTypeCases(layoutGroup, m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(),
427 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
428 }
429
430 if (glu::isDataTypeMatrix(type))
431 {
432 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
433 {
434 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
435 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + precisionFlags[precNdx].name + "_" + typeName).c_str(),
436 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
437 }
438 }
439 }
440 }
441 }
442
443 // ubo.single_basic_array
444 {
445 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
446 addChild(singleBasicArrayGroup);
447
448 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
449 {
450 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
451 singleBasicArrayGroup->addChild(layoutGroup);
452
453 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
454 {
455 glu::DataType type = basicTypes[basicTypeNdx];
456 const char* typeName = glu::getDataTypeName(type);
457 const int arraySize = 3;
458
459 createBlockBasicTypeCases(layoutGroup, m_context, typeName,
460 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize),
461 layoutFlags[layoutFlagNdx].flags);
462
463 if (glu::isDataTypeMatrix(type))
464 {
465 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
466 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
467 VarType(VarType(type, PRECISION_HIGH), arraySize),
468 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
469 }
470 }
471 }
472 }
473
474 // ubo.single_struct
475 {
476 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
477 addChild(singleStructGroup);
478
479 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
480 {
481 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
482 singleStructGroup->addChild(modeGroup);
483
484 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
485 {
486 for (int isArray = 0; isArray < 2; isArray++)
487 {
488 std::string baseName = layoutFlags[layoutFlagNdx].name;
489 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
490
491 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
492 continue; // Doesn't make sense to add this variant.
493
494 if (isArray)
495 baseName += "_instance_array";
496
497 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
498 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
499
500 if (!(baseFlags & LAYOUT_PACKED))
501 modeGroup->addChild(new BlockSingleStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
502 }
503 }
504 }
505 }
506
507 // ubo.single_struct_array
508 {
509 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
510 addChild(singleStructArrayGroup);
511
512 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
513 {
514 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
515 singleStructArrayGroup->addChild(modeGroup);
516
517 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
518 {
519 for (int isArray = 0; isArray < 2; isArray++)
520 {
521 std::string baseName = layoutFlags[layoutFlagNdx].name;
522 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
523
524 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
525 continue; // Doesn't make sense to add this variant.
526
527 if (isArray)
528 baseName += "_instance_array";
529
530 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
531 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
532
533 if (!(baseFlags & LAYOUT_PACKED))
534 modeGroup->addChild(new BlockSingleStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
535 }
536 }
537 }
538 }
539
540 // ubo.single_nested_struct
541 {
542 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
543 addChild(singleNestedStructGroup);
544
545 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
546 {
547 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
548 singleNestedStructGroup->addChild(modeGroup);
549
550 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
551 {
552 for (int isArray = 0; isArray < 2; isArray++)
553 {
554 std::string baseName = layoutFlags[layoutFlagNdx].name;
555 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
556
557 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
558 continue; // Doesn't make sense to add this variant.
559
560 if (isArray)
561 baseName += "_instance_array";
562
563 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
564 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
565
566 if (!(baseFlags & LAYOUT_PACKED))
567 modeGroup->addChild(new BlockSingleNestedStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
568 }
569 }
570 }
571 }
572
573 // ubo.single_nested_struct_array
574 {
575 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
576 addChild(singleNestedStructArrayGroup);
577
578 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
579 {
580 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
581 singleNestedStructArrayGroup->addChild(modeGroup);
582
583 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
584 {
585 for (int isArray = 0; isArray < 2; isArray++)
586 {
587 std::string baseName = layoutFlags[layoutFlagNdx].name;
588 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
589
590 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
591 continue; // Doesn't make sense to add this variant.
592
593 if (isArray)
594 baseName += "_instance_array";
595
596 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
597 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
598
599 if (!(baseFlags & LAYOUT_PACKED))
600 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
601 }
602 }
603 }
604 }
605
606 // ubo.instance_array_basic_type
607 {
608 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
609 addChild(instanceArrayBasicTypeGroup);
610
611 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
612 {
613 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
614 instanceArrayBasicTypeGroup->addChild(layoutGroup);
615
616 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
617 {
618 glu::DataType type = basicTypes[basicTypeNdx];
619 const char* typeName = glu::getDataTypeName(type);
620 const int numInstances = 3;
621
622 createBlockBasicTypeCases(layoutGroup, m_context, typeName,
623 VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH),
624 layoutFlags[layoutFlagNdx].flags, numInstances);
625
626 if (glu::isDataTypeMatrix(type))
627 {
628 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
629 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
630 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags,
631 numInstances);
632 }
633 }
634 }
635 }
636
637 // ubo.multi_basic_types
638 {
639 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
640 addChild(multiBasicTypesGroup);
641
642 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
643 {
644 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
645 multiBasicTypesGroup->addChild(modeGroup);
646
647 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
648 {
649 for (int isArray = 0; isArray < 2; isArray++)
650 {
651 std::string baseName = layoutFlags[layoutFlagNdx].name;
652 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
653
654 if (isArray)
655 baseName += "_instance_array";
656
657 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
658 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
659
660 if (!(baseFlags & LAYOUT_PACKED))
661 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
662
663 modeGroup->addChild(new BlockMultiBasicTypesCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
664 }
665 }
666 }
667 }
668
669 // ubo.multi_nested_struct
670 {
671 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
672 addChild(multiNestedStructGroup);
673
674 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
675 {
676 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
677 multiNestedStructGroup->addChild(modeGroup);
678
679 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
680 {
681 for (int isArray = 0; isArray < 2; isArray++)
682 {
683 std::string baseName = layoutFlags[layoutFlagNdx].name;
684 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
685
686 if (isArray)
687 baseName += "_instance_array";
688
689 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
690 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
691
692 if (!(baseFlags & LAYOUT_PACKED))
693 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
694
695 modeGroup->addChild(new BlockMultiNestedStructCase(m_context, (baseName + "_mixed").c_str(), "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
696 }
697 }
698 }
699 }
700
701 // ubo.random
702 {
703 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
704 const deUint32 allLayouts = FEATURE_PACKED_LAYOUT|FEATURE_SHARED_LAYOUT|FEATURE_STD140_LAYOUT;
705 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES;
706 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
707 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT;
708 const deUint32 allFeatures = ~FEATURE_ARRAYS_OF_ARRAYS;
709
710 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
711 addChild(randomGroup);
712
713 // Basic types.
714 createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused, 25, 0);
715 createRandomCaseGroup(randomGroup, m_context, "vector_types", "Scalar and vector types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|FEATURE_VECTORS, 25, 25);
716 createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50);
717 createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50);
718
719 createRandomCaseGroup(randomGroup, m_context, "basic_instance_arrays", "Basic instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_INSTANCE_ARRAYS, 25, 75);
720 createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100);
721 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS, 25, 150);
722 createRandomCaseGroup(randomGroup, m_context, "nested_structs_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS, 25, 125);
723 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS, 25, 175);
724
725 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 200);
726 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 250);
727 }
728 }
729
730 } // Functional
731 } // gles3
732 } // deqp
733