1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
8 * Copyright (c) 2018 The Khronos Group Inc.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief Vulkan Transform Feedback Fuzz Layout Tests
25 *//*--------------------------------------------------------------------*/
26
27 #include "vktTransformFeedbackFuzzLayoutCase.hpp"
28 #include "vktTransformFeedbackRandomLayoutCase.hpp"
29
30 #include "tcuCommandLine.hpp"
31 #include "deStringUtil.hpp"
32
33 namespace vkt
34 {
35 namespace TransformFeedback
36 {
37
38 namespace
39 {
40
41 class BlockBasicTypeCase : public InterfaceBlockCase
42 {
43 public:
BlockBasicTypeCase(tcu::TestContext & testCtx,const std::string & name,const VarType & type,deUint32 layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)44 BlockBasicTypeCase (tcu::TestContext& testCtx,
45 const std::string& name,
46 const VarType& type,
47 deUint32 layoutFlags,
48 int numInstances,
49 MatrixLoadFlags matrixLoadFlag,
50 TestStageFlags testStageFlags)
51 : InterfaceBlockCase(testCtx, name, matrixLoadFlag, testStageFlags)
52 {
53 InterfaceBlock& block = m_interface.allocBlock("Block");
54 block.addInterfaceMember(InterfaceBlockMember("var", type, 0));
55
56 VarType tempType = type;
57 while (tempType.isArrayType())
58 {
59 tempType = tempType.getElementType();
60 }
61
62 block.setFlags(layoutFlags);
63
64 if (numInstances > 0)
65 {
66 block.setArraySize(numInstances);
67 block.setInstanceName("block");
68 }
69 }
70 };
71
createBlockBasicTypeCases(tcu::TestCaseGroup & group,tcu::TestContext & testCtx,const std::string & name,const VarType & type,deUint32 layoutFlags,int numInstances=0)72 void createBlockBasicTypeCases (tcu::TestCaseGroup& group, tcu::TestContext& testCtx, const std::string& name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
73 {
74 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(group.getTestContext(), name.c_str()));
75
76 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex", type, layoutFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
77 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "geometry", type, layoutFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
78
79 group.addChild(typeGroup.release());
80 }
81
82 class BlockSingleStructCase : public InterfaceBlockCase
83 {
84 public:
BlockSingleStructCase(tcu::TestContext & testCtx,const std::string & name,deUint32 layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)85 BlockSingleStructCase (tcu::TestContext& testCtx,
86 const std::string& name,
87 deUint32 layoutFlags,
88 int numInstances,
89 MatrixLoadFlags matrixLoadFlag,
90 TestStageFlags testStageFlags)
91 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
92 {
93 StructType& typeS = m_interface.allocStruct("S");
94 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED); // First member is unused.
95 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_VEC3, PRECISION_HIGH), 2));
96 typeS.addMember("c", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
97
98 InterfaceBlock& block = m_interface.allocBlock("Block");
99 block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
100 block.setFlags(layoutFlags);
101
102 if (numInstances > 0)
103 {
104 block.setInstanceName("block");
105 block.setArraySize(numInstances);
106 }
107 }
108 };
109
110 class BlockSingleStructArrayCase : public InterfaceBlockCase
111 {
112 public:
BlockSingleStructArrayCase(tcu::TestContext & testCtx,const std::string & name,deUint32 layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)113 BlockSingleStructArrayCase (tcu::TestContext& testCtx,
114 const std::string& name,
115 deUint32 layoutFlags,
116 int numInstances,
117 MatrixLoadFlags matrixLoadFlag,
118 TestStageFlags testStageFlags)
119 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
120 {
121 StructType& typeS = m_interface.allocStruct("S");
122 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED);
123 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 2));
124 typeS.addMember("c", VarType(glu::TYPE_FLOAT, PRECISION_HIGH));
125
126 InterfaceBlock& block = m_interface.allocBlock("Block");
127 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
128 block.addInterfaceMember(InterfaceBlockMember("s", VarType(VarType(&typeS), 2)));
129 block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
130 block.setFlags(layoutFlags);
131
132 if (numInstances > 0)
133 {
134 block.setInstanceName("block");
135 block.setArraySize(numInstances);
136 }
137 }
138 };
139
140 class BlockSingleNestedStructCase : public InterfaceBlockCase
141 {
142 public:
BlockSingleNestedStructCase(tcu::TestContext & testCtx,const std::string & name,deUint32 layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)143 BlockSingleNestedStructCase (tcu::TestContext& testCtx,
144 const std::string& name,
145 deUint32 layoutFlags,
146 int numInstances,
147 MatrixLoadFlags matrixLoadFlag,
148 TestStageFlags testStageFlags)
149 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
150 {
151 StructType& typeS = m_interface.allocStruct("S");
152 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
153 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 2));
154 typeS.addMember("c", VarType(glu::TYPE_FLOAT, PRECISION_HIGH), FIELD_UNASSIGNED);
155
156 StructType& typeT = m_interface.allocStruct("T");
157 typeT.addMember("a", VarType(glu::TYPE_FLOAT_VEC3, PRECISION_MEDIUM));
158 typeT.addMember("b", VarType(&typeS));
159
160 InterfaceBlock& block = m_interface.allocBlock("Block");
161 block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
162 block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_UINT, PRECISION_LOW), FIELD_UNASSIGNED));
163 block.addInterfaceMember(InterfaceBlockMember("t", VarType(&typeT), 0));
164 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_HIGH), 0));
165 block.setFlags(layoutFlags);
166
167 if (numInstances > 0)
168 {
169 block.setInstanceName("block");
170 block.setArraySize(numInstances);
171 }
172 }
173 };
174
175 class BlockSingleNestedStructArrayCase : public InterfaceBlockCase
176 {
177 public:
BlockSingleNestedStructArrayCase(tcu::TestContext & testCtx,const std::string & name,deUint32 layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)178 BlockSingleNestedStructArrayCase (tcu::TestContext& testCtx,
179 const std::string& name,
180 deUint32 layoutFlags,
181 int numInstances,
182 MatrixLoadFlags matrixLoadFlag,
183 TestStageFlags testStageFlags)
184 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
185 {
186 StructType& typeS = m_interface.allocStruct("S");
187 typeS.addMember("a", VarType(VarType(glu::TYPE_FLOAT, PRECISION_HIGH), 2));
188
189 StructType& typeT = m_interface.allocStruct("T");
190 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM));
191 typeT.addMember("b", VarType(VarType(&typeS), 2));
192
193 InterfaceBlock& block = m_interface.allocBlock("Block");
194 block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
195 block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), FIELD_UNASSIGNED));
196 block.addInterfaceMember(InterfaceBlockMember("t", VarType(VarType(&typeT), 2), 0));
197 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
198 block.setFlags(layoutFlags);
199
200 if (numInstances > 0)
201 {
202 block.setInstanceName("block");
203 block.setArraySize(numInstances);
204 }
205 }
206 };
207
208 class BlockMultiBasicTypesCase : public InterfaceBlockCase
209 {
210 public:
BlockMultiBasicTypesCase(tcu::TestContext & testCtx,const std::string & name,deUint32 flagsA,deUint32 flagsB,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)211 BlockMultiBasicTypesCase (tcu::TestContext& testCtx,
212 const std::string& name,
213 deUint32 flagsA,
214 deUint32 flagsB,
215 int numInstances,
216 MatrixLoadFlags matrixLoadFlag,
217 TestStageFlags testStageFlags)
218 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
219 {
220 InterfaceBlock& blockA = m_interface.allocBlock("BlockA");
221 blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
222 blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), FIELD_UNASSIGNED));
223 blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
224 blockA.setInstanceName("blockA");
225 blockA.setFlags(flagsA);
226
227 InterfaceBlock& blockB = m_interface.allocBlock("BlockB");
228 blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
229 blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
230 blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), FIELD_UNASSIGNED));
231 blockB.addInterfaceMember(InterfaceBlockMember("d", VarType(glu::TYPE_INT, 0)));
232 blockB.setInstanceName("blockB");
233 blockB.setFlags(flagsB);
234
235 if (numInstances > 0)
236 {
237 blockA.setArraySize(numInstances);
238 blockB.setArraySize(numInstances);
239 }
240 }
241 };
242
243 class BlockMultiNestedStructCase : public InterfaceBlockCase
244 {
245 public:
BlockMultiNestedStructCase(tcu::TestContext & testCtx,const std::string & name,deUint32 flagsA,deUint32 flagsB,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)246 BlockMultiNestedStructCase (tcu::TestContext& testCtx,
247 const std::string& name,
248 deUint32 flagsA,
249 deUint32 flagsB,
250 int numInstances,
251 MatrixLoadFlags matrixLoadFlag,
252 TestStageFlags testStageFlags)
253 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
254 {
255 StructType& typeS = m_interface.allocStruct("S");
256 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_LOW));
257 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 2));
258
259 StructType& typeT = m_interface.allocStruct("T");
260 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), FIELD_UNASSIGNED);
261 typeT.addMember("b", VarType(&typeS));
262 typeT.addMember("c", VarType(glu::TYPE_UINT_VEC3, 0));
263
264 InterfaceBlock& blockA = m_interface.allocBlock("BlockA");
265 blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
266 blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeS)));
267 blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW), FIELD_UNASSIGNED));
268 blockA.setInstanceName("blockA");
269 blockA.setFlags(flagsA);
270
271 InterfaceBlock& blockB = m_interface.allocBlock("BlockB");
272 blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
273 blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeT)));
274 blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_INT, 0)));
275 blockB.setInstanceName("blockB");
276 blockB.setFlags(flagsB);
277
278 if (numInstances > 0)
279 {
280 blockA.setArraySize(numInstances);
281 blockB.setArraySize(numInstances);
282 }
283 }
284 };
285
286 class BlockVariousBuffersCase : public InterfaceBlockCase
287 {
288 public:
BlockVariousBuffersCase(tcu::TestContext & testCtx,const std::string & name,deUint32 flags,deUint32 xfbBufferA,deUint32 xfbBufferB,deUint32 xfbBufferC,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)289 BlockVariousBuffersCase (tcu::TestContext& testCtx,
290 const std::string& name,
291 deUint32 flags,
292 deUint32 xfbBufferA,
293 deUint32 xfbBufferB,
294 deUint32 xfbBufferC,
295 int numInstances,
296 MatrixLoadFlags matrixLoadFlag,
297 TestStageFlags testStageFlags)
298 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
299 {
300 StructType& typeS = m_interface.allocStruct("S");
301 typeS.addMember("a", VarType(VarType(glu::TYPE_FLOAT, PRECISION_LOW), 3));
302 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM), 2));
303 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
304
305 StructType& typeT = m_interface.allocStruct("T");
306 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), FIELD_UNASSIGNED);
307 typeT.addMember("b", VarType(glu::TYPE_INT_VEC3, 0));
308
309 InterfaceBlock& blockA = m_interface.allocBlock("BlockA");
310 blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_INT, PRECISION_HIGH)));
311 blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeS)));
312 blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), FIELD_UNASSIGNED));
313 blockA.setInstanceName("blockA");
314 blockA.setFlags(flags);
315 blockA.setXfbBuffer(xfbBufferA);
316
317 InterfaceBlock& blockB = m_interface.allocBlock("BlockB");
318 blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
319 blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeT)));
320 blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_INT_VEC4, 0), FIELD_UNASSIGNED));
321 blockB.addInterfaceMember(InterfaceBlockMember("d", VarType(glu::TYPE_INT, 0)));
322 blockB.setInstanceName("blockB");
323 blockB.setFlags(flags);
324 blockB.setXfbBuffer(xfbBufferB);
325
326 InterfaceBlock& blockC = m_interface.allocBlock("BlockC");
327 blockC.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_UINT, PRECISION_HIGH)));
328 blockC.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_HIGH)));
329 blockC.setInstanceName("blockC");
330 blockC.setFlags(flags);
331 blockC.setXfbBuffer(xfbBufferC);
332
333 if (numInstances > 0)
334 {
335 blockA.setArraySize(numInstances);
336 blockB.setArraySize(numInstances);
337 }
338 }
339 };
340
341 class Block2LevelStructArrayCase : public InterfaceBlockCase
342 {
343 public:
Block2LevelStructArrayCase(tcu::TestContext & testCtx,const std::string & name,deUint32 flags,int numInstances,MatrixLoadFlags matrixLoadFlag,TestStageFlags testStageFlags)344 Block2LevelStructArrayCase (tcu::TestContext& testCtx,
345 const std::string& name,
346 deUint32 flags,
347 int numInstances,
348 MatrixLoadFlags matrixLoadFlag,
349 TestStageFlags testStageFlags)
350 : InterfaceBlockCase (testCtx, name, matrixLoadFlag, testStageFlags)
351 {
352 StructType& typeS = m_interface.allocStruct("S");
353 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED);
354 typeS.addMember("b", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM));
355
356 InterfaceBlock& block = m_interface.allocBlock("Block");
357 block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM)));
358 block.addInterfaceMember(InterfaceBlockMember("s", VarType(VarType(VarType(&typeS), 2), 2)));
359 block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM)));
360 block.setFlags(flags);
361
362 if (numInstances > 0)
363 {
364 block.setInstanceName("block");
365 block.setArraySize(numInstances);
366 }
367 }
368 };
369
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,tcu::TestContext & testCtx,const char * groupName,deUint32 numCases,TestStageFlags testStageFlags,deUint32 features)370 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, deUint32 numCases, TestStageFlags testStageFlags, deUint32 features)
371 {
372 const deUint32 baseSeed = deStringHash(groupName) + static_cast<deUint32>(testCtx.getCommandLine().getBaseSeed());
373 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName);
374
375 parentGroup->addChild(group);
376
377 for (deUint32 ndx = 0; ndx < numCases; ndx++)
378 group->addChild(new RandomInterfaceBlockCase(testCtx, de::toString(ndx), testStageFlags, features, ndx + baseSeed));
379 }
380
381 // InterfaceBlockTests
382
383 class InterfaceBlockTests : public tcu::TestCaseGroup
384 {
385 public:
386 InterfaceBlockTests (tcu::TestContext& testCtx);
387 ~InterfaceBlockTests (void);
388
389 void init (void);
390
391 private:
392 InterfaceBlockTests (const InterfaceBlockTests& other);
393 InterfaceBlockTests& operator= (const InterfaceBlockTests& other);
394 };
395
InterfaceBlockTests(tcu::TestContext & testCtx)396 InterfaceBlockTests::InterfaceBlockTests (tcu::TestContext& testCtx)
397 : TestCaseGroup(testCtx, "fuzz")
398 {
399 }
400
~InterfaceBlockTests(void)401 InterfaceBlockTests::~InterfaceBlockTests (void)
402 {
403 }
404
init(void)405 void InterfaceBlockTests::init (void)
406 {
407 static const glu::DataType basicTypes[] =
408 {
409 glu::TYPE_FLOAT,
410 glu::TYPE_FLOAT_VEC2,
411 glu::TYPE_FLOAT_VEC3,
412 glu::TYPE_FLOAT_VEC4,
413 glu::TYPE_INT,
414 glu::TYPE_INT_VEC2,
415 glu::TYPE_INT_VEC3,
416 glu::TYPE_INT_VEC4,
417 glu::TYPE_UINT,
418 glu::TYPE_UINT_VEC2,
419 glu::TYPE_UINT_VEC3,
420 glu::TYPE_UINT_VEC4,
421 glu::TYPE_FLOAT_MAT2,
422 glu::TYPE_FLOAT_MAT3,
423 glu::TYPE_FLOAT_MAT4,
424 glu::TYPE_FLOAT_MAT2X3,
425 glu::TYPE_FLOAT_MAT2X4,
426 glu::TYPE_FLOAT_MAT3X2,
427 glu::TYPE_FLOAT_MAT3X4,
428 glu::TYPE_FLOAT_MAT4X2,
429 glu::TYPE_FLOAT_MAT4X3,
430 glu::TYPE_DOUBLE,
431 glu::TYPE_DOUBLE_VEC2,
432 glu::TYPE_DOUBLE_VEC3,
433 glu::TYPE_DOUBLE_VEC4,
434 glu::TYPE_DOUBLE_MAT2,
435 glu::TYPE_DOUBLE_MAT2X3,
436 glu::TYPE_DOUBLE_MAT2X4,
437 glu::TYPE_DOUBLE_MAT3X2,
438 glu::TYPE_DOUBLE_MAT3,
439 glu::TYPE_DOUBLE_MAT3X4,
440 glu::TYPE_DOUBLE_MAT4X2,
441 glu::TYPE_DOUBLE_MAT4X3,
442 glu::TYPE_DOUBLE_MAT4,
443 };
444
445 static const struct
446 {
447 const std::string name;
448 deUint32 flags;
449 } precisionFlags[] =
450 {
451 // TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision?
452 { "lowp", PRECISION_LOW },
453 { "mediump", PRECISION_MEDIUM },
454 { "highp", PRECISION_HIGH }
455 };
456 const deUint32 defaultFlags = LAYOUT_XFBBUFFER | LAYOUT_XFBOFFSET;
457
458 // .2_level_array
459 {
460 // 2-level basic array variable in single buffer
461 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array");
462 addChild(nestedArrayGroup);
463
464 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
465 {
466 const glu::DataType type = basicTypes[basicTypeNdx];
467 const char* const typeName = glu::getDataTypeName(type);
468 const int childSize = 2;
469 const int parentSize = 2;
470 const VarType childType (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize);
471 const VarType parentType (childType, parentSize);
472
473 createBlockBasicTypeCases(*nestedArrayGroup, m_testCtx, typeName, parentType, defaultFlags);
474 }
475 }
476
477 // .3_level_array
478 {
479 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
480 addChild(nestedArrayGroup);
481
482 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
483 {
484 const glu::DataType type = basicTypes[basicTypeNdx];
485 const char* const typeName = glu::getDataTypeName(type);
486 const int childSize0 = 2;
487 const int childSize1 = 2;
488 const int parentSize = 2;
489 const VarType childType0 (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize0);
490 const VarType childType1 (childType0, childSize1);
491 const VarType parentType (childType1, parentSize);
492
493 createBlockBasicTypeCases(*nestedArrayGroup, m_testCtx, typeName, parentType, defaultFlags);
494 }
495 }
496
497 // .2_level_struct_array
498 {
499 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one interface block");
500 addChild(structArrayArrayGroup);
501
502 for (int isArray = 0; isArray < 2; isArray++)
503 {
504 const std::string baseName = isArray ? "instance_array" : "std";
505 const int numInstances = isArray ? 2 : 0;
506
507 structArrayArrayGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex"), defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
508 structArrayArrayGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_geometry"), defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
509 }
510 }
511
512 // .single_basic_type
513 {
514 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
515 addChild(singleBasicTypeGroup);
516
517 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
518 {
519 glu::DataType type = basicTypes[basicTypeNdx];
520 const char* const typeName = glu::getDataTypeName(type);
521
522 if (!dataTypeSupportsPrecisionModifier(type))
523 createBlockBasicTypeCases(*singleBasicTypeGroup, m_testCtx, typeName, VarType(type, 0), defaultFlags);
524 }
525
526 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
527 {
528 de::MovePtr<tcu::TestCaseGroup> precGroup(new tcu::TestCaseGroup(m_testCtx, precisionFlags[precNdx].name.c_str()));
529
530 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
531 {
532 glu::DataType type = basicTypes[basicTypeNdx];
533 const char* const typeName = glu::getDataTypeName(type);
534
535 if (dataTypeSupportsPrecisionModifier(type))
536 createBlockBasicTypeCases(*precGroup, m_testCtx, typeName, VarType(type, precisionFlags[precNdx].flags), defaultFlags);
537 }
538 singleBasicTypeGroup->addChild(precGroup.release());
539 }
540 }
541
542 // .single_basic_array
543 {
544 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
545 addChild(singleBasicArrayGroup);
546
547 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
548 {
549 glu::DataType type = basicTypes[basicTypeNdx];
550 const char* const typeName = glu::getDataTypeName(type);
551 const int arraySize = 3;
552
553 createBlockBasicTypeCases(*singleBasicArrayGroup, m_testCtx, typeName,
554 VarType(VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), arraySize),
555 defaultFlags);
556 }
557 }
558
559 // .single_struct
560 {
561 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in interface block");
562 addChild(singleStructGroup);
563
564 for (int isArray = 0; isArray < 2; isArray++)
565 {
566 const std::string baseName = isArray ? "instance_array" : "std";
567 const int numInstances = isArray ? 3 : 0;
568
569 singleStructGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
570 singleStructGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_geometry", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
571 }
572 }
573
574 // .single_struct_array
575 {
576 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one interface block");
577 addChild(singleStructArrayGroup);
578
579 for (int isArray = 0; isArray < 2; isArray++)
580 {
581 const std::string baseName = isArray ? "instance_array" : "std";
582 const int numInstances = isArray ? 2 : 0;
583
584 singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
585 singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_geometry", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
586 }
587 }
588
589 // .single_nested_struct
590 {
591 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one interface block");
592 addChild(singleNestedStructGroup);
593
594 for (int isArray = 0; isArray < 2; isArray++)
595 {
596 const std::string baseName = isArray ? "instance_array" : "std";
597 const int numInstances = isArray ? 2 : 0;
598
599 singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
600 singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_geometry", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
601 }
602 }
603
604 // .single_nested_struct_array
605 {
606 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one interface block");
607 addChild(singleNestedStructArrayGroup);
608
609 for (int isArray = 0; isArray < 2; isArray++)
610 {
611 const std::string baseName = isArray ? "instance_array" : "std";
612 const int numInstances = isArray ? 2 : 0;
613
614 singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
615 singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_geometry", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
616 }
617 }
618
619 // .instance_array_basic_type
620 {
621 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
622 addChild(instanceArrayBasicTypeGroup);
623
624 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
625 {
626 glu::DataType type = basicTypes[basicTypeNdx];
627 const char* const typeName = glu::getDataTypeName(type);
628 const int numInstances = 3;
629
630 createBlockBasicTypeCases(*instanceArrayBasicTypeGroup, m_testCtx, typeName,
631 VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH),
632 defaultFlags, numInstances);
633 }
634 }
635
636 // .multi_basic_types
637 {
638 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
639 addChild(multiBasicTypesGroup);
640
641 for (int isArray = 0; isArray < 2; isArray++)
642 {
643 const std::string baseName = isArray ? "instance_array" : "std";
644 const int numInstances = isArray ? 2 : 0;
645
646 multiBasicTypesGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
647 multiBasicTypesGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_geometry", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
648 }
649 }
650
651 // .multi_nested_struct
652 {
653 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
654 addChild(multiNestedStructGroup);
655
656 for (int isArray = 0; isArray < 2; isArray++)
657 {
658 const std::string baseName = isArray ? "instance_array" : "std";
659 const int numInstances = isArray ? 2 : 0;
660
661 multiNestedStructGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
662 multiNestedStructGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_geometry", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
663 }
664 }
665
666 // .various_buffers
667 {
668 static const struct
669 {
670 const std::string name;
671 deUint32 bufferA;
672 deUint32 bufferB;
673 deUint32 bufferC;
674 } xfbBufferNumbers[] =
675 {
676 { "000", 0, 0, 0 },
677 { "010", 0, 1, 0 },
678 { "100", 1, 0, 0 },
679 { "110", 1, 1, 0 },
680 };
681
682 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "various_buffers", "Output data into several transform feedback buffers");
683 addChild(multiNestedStructGroup);
684
685 for (int xfbBufferNdx = 0; xfbBufferNdx < DE_LENGTH_OF_ARRAY(xfbBufferNumbers); xfbBufferNdx++)
686 {
687 const deUint32 bufferA = xfbBufferNumbers[xfbBufferNdx].bufferA;
688 const deUint32 bufferB = xfbBufferNumbers[xfbBufferNdx].bufferB;
689 const deUint32 bufferC = xfbBufferNumbers[xfbBufferNdx].bufferC;
690
691 for (int isArray = 0; isArray < 2; isArray++)
692 {
693 std::string baseName = "buffers" + xfbBufferNumbers[xfbBufferNdx].name;
694 const int numInstances = isArray ? 2 : 0;
695
696 if (isArray)
697 baseName += "_instance_array";
698
699 multiNestedStructGroup->addChild(new BlockVariousBuffersCase(m_testCtx, baseName + "_vertex", defaultFlags, bufferA, bufferB, bufferC, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
700 multiNestedStructGroup->addChild(new BlockVariousBuffersCase(m_testCtx, baseName + "_geometry", defaultFlags, bufferA, bufferB, bufferC, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
701 }
702 }
703 }
704
705 // .random
706 {
707 static const struct
708 {
709 std::string name;
710 TestStageFlags testStageFlags;
711 }
712 stages[] =
713 {
714 { "vertex", TEST_STAGE_VERTEX },
715 { "geometry", TEST_STAGE_GEOMETRY },
716 };
717
718 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
719 {
720 const std::string groupName = "random_" + stages[stageNdx].name;
721 const TestStageFlags stage = stages[stageNdx].testStageFlags;
722 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES|FEATURE_DOUBLES;
723 const deUint32 unused = FEATURE_UNASSIGNED_FIELDS|FEATURE_UNASSIGNED_BLOCK_MEMBERS;
724 const deUint32 disabled = FEATURE_INSTANCE_ARRAYS|FEATURE_MISSING_BLOCK_MEMBERS|FEATURE_OUT_OF_ORDER_OFFSETS; // OOO & missing offsets handled in a dedicated case group
725 const deUint32 allFeatures = ~disabled;
726 const deUint32 numCases = 50;
727
728 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, groupName.c_str(), "Random Interface Block cases");
729 addChild(group);
730
731 // Scalar types only, per-block buffers
732 createRandomCaseGroup(group, m_testCtx, "scalar_types", numCases, stage, unused );
733 // Scalar and vector types only, per-block buffers
734 createRandomCaseGroup(group, m_testCtx, "vector_types", numCases, stage, unused|FEATURE_VECTORS );
735 // All basic types, per-block buffers
736 createRandomCaseGroup(group, m_testCtx, "basic_types", numCases, stage, unused|allBasicTypes );
737 // Arrays, per-block buffers
738 createRandomCaseGroup(group, m_testCtx, "basic_arrays", numCases, stage, unused|allBasicTypes|FEATURE_ARRAYS);
739
740 // Basic instance arrays, per-block buffers
741 createRandomCaseGroup(group, m_testCtx, "basic_instance_arrays", numCases, stage, unused|allBasicTypes|FEATURE_INSTANCE_ARRAYS );
742 // Nested structs, per-block buffers
743 createRandomCaseGroup(group, m_testCtx, "nested_structs", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS );
744 // Nested structs, arrays, per-block buffers
745 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_ARRAYS );
746 // Nested structs, instance arrays, per-block buffers
747 createRandomCaseGroup(group, m_testCtx, "nested_structs_instance_arrays", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS );
748 // Nested structs, instance arrays, per-block buffers
749 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays_instance_arrays", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS);
750
751 // All random features, shared buffer
752 createRandomCaseGroup(group, m_testCtx, "all_instance_array", numCases*2, stage, allFeatures|FEATURE_INSTANCE_ARRAYS);
753 // All random features, out of order member offsets
754 createRandomCaseGroup(group, m_testCtx, "all_unordered_and_instance_array", numCases*2, stage, allFeatures|FEATURE_OUT_OF_ORDER_OFFSETS|FEATURE_INSTANCE_ARRAYS);
755 // All random features, missing interface members
756 createRandomCaseGroup(group, m_testCtx, "all_missing", numCases*2, stage, allFeatures|FEATURE_MISSING_BLOCK_MEMBERS);
757 // All random features, unordered and missing members
758 createRandomCaseGroup(group, m_testCtx, "all_unordered_and_missing", numCases*2, stage, allFeatures|FEATURE_OUT_OF_ORDER_OFFSETS|FEATURE_MISSING_BLOCK_MEMBERS);
759 }
760 }
761 }
762
763 } // anonymous
764
createTransformFeedbackFuzzLayoutTests(tcu::TestContext & testCtx)765 tcu::TestCaseGroup* createTransformFeedbackFuzzLayoutTests (tcu::TestContext& testCtx)
766 {
767 return new InterfaceBlockTests(testCtx);
768 }
769
770 } // TransformFeedback
771 } // vkt
772