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 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Uniform block tests.
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktUniformBlockTests.hpp"
27
28 #include "vktUniformBlockCase.hpp"
29 #include "vktRandomUniformBlockCase.hpp"
30
31 #include "tcuCommandLine.hpp"
32 #include "deStringUtil.hpp"
33
34 namespace vkt
35 {
36 namespace ubo
37 {
38
39 namespace
40 {
41
42 class BlockBasicTypeCase : public UniformBlockCase
43 {
44 public:
BlockBasicTypeCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const VarType & type,deUint32 layoutFlags,int numInstances,MatrixLoadFlags matrixLoadFlag)45 BlockBasicTypeCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const VarType& type, deUint32 layoutFlags, int numInstances, MatrixLoadFlags matrixLoadFlag)
46 : UniformBlockCase(testCtx, name, description, BUFFERMODE_PER_BLOCK, matrixLoadFlag)
47 {
48 VarType tempType = type;
49 while (tempType.isArrayType())
50 {
51 tempType = tempType.getElementType();
52 }
53 if (getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_UINT16 ||
54 getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_INT16 ||
55 getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_FLOAT16)
56 {
57 layoutFlags |= LAYOUT_16BIT_STORAGE;
58 }
59 if (getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_UINT8 ||
60 getDataTypeScalarType(tempType.getBasicType()) == glu::TYPE_INT8)
61 {
62 layoutFlags |= LAYOUT_8BIT_STORAGE;
63 }
64
65 UniformBlock& block = m_interface.allocBlock("Block");
66 // For scalar layout tests with non-scalar types, add a scalar padding variable
67 // before "var", to make var only be scalar aligned.
68 if ((layoutFlags & LAYOUT_SCALAR) && !isDataTypeScalar(type.getBasicType())) {
69 block.addUniform(Uniform("padding", VarType(getDataTypeScalarType(tempType.getBasicType()), 0), 0));
70 }
71 block.addUniform(Uniform("var", type, 0));
72
73 block.setFlags(layoutFlags);
74
75 if (numInstances > 0)
76 {
77 block.setArraySize(numInstances);
78 block.setInstanceName("block");
79 }
80 }
81 };
82
createBlockBasicTypeCases(tcu::TestCaseGroup & group,tcu::TestContext & testCtx,const std::string & name,const VarType & type,deUint32 layoutFlags,int numInstances=0)83 void createBlockBasicTypeCases (tcu::TestCaseGroup& group, tcu::TestContext& testCtx, const std::string& name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
84 {
85 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(group.getTestContext(), name.c_str(), ""));
86
87 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex", "", type, layoutFlags|DECLARE_VERTEX, numInstances, LOAD_FULL_MATRIX));
88 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "fragment", "", type, layoutFlags|DECLARE_FRAGMENT, numInstances, LOAD_FULL_MATRIX));
89 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "both", "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances, LOAD_FULL_MATRIX));
90 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex_comp_access", "", type, layoutFlags|DECLARE_VERTEX, numInstances, LOAD_MATRIX_COMPONENTS));
91 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "fragment_comp_access", "", type, layoutFlags|DECLARE_FRAGMENT, numInstances, LOAD_MATRIX_COMPONENTS));
92 typeGroup->addChild(new BlockBasicTypeCase(testCtx, "both_comp_access", "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances, LOAD_MATRIX_COMPONENTS));
93
94 group.addChild(typeGroup.release());
95 }
96
97 class BlockSingleStructCase : public UniformBlockCase
98 {
99 public:
BlockSingleStructCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)100 BlockSingleStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
101 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
102 {
103 StructType& typeS = m_interface.allocStruct("S");
104 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
105 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
106 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
107
108 UniformBlock& block = m_interface.allocBlock("Block");
109 block.addUniform(Uniform("s", VarType(&typeS), 0));
110 block.setFlags(layoutFlags);
111
112 if (numInstances > 0)
113 {
114 block.setInstanceName("block");
115 block.setArraySize(numInstances);
116 }
117 }
118 };
119
120 class BlockSingleStructArrayCase : public UniformBlockCase
121 {
122 public:
BlockSingleStructArrayCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)123 BlockSingleStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
124 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
125 {
126 StructType& typeS = m_interface.allocStruct("S");
127 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
128 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
129 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
130
131 UniformBlock& block = m_interface.allocBlock("Block");
132 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
133 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
134 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
135 block.setFlags(layoutFlags);
136
137 if (numInstances > 0)
138 {
139 block.setInstanceName("block");
140 block.setArraySize(numInstances);
141 }
142 }
143 };
144
145 class BlockSingleNestedStructCase : public UniformBlockCase
146 {
147 public:
BlockSingleNestedStructCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)148 BlockSingleNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
149 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
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_MAT3, PRECISION_MEDIUM), 4));
154 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
155
156 StructType& typeT = m_interface.allocStruct("T");
157 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
158 typeT.addMember("b", VarType(&typeS));
159
160 UniformBlock& block = m_interface.allocBlock("Block");
161 block.addUniform(Uniform("s", VarType(&typeS), 0));
162 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
163 block.addUniform(Uniform("t", VarType(&typeT), 0));
164 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, 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 UniformBlockCase
176 {
177 public:
BlockSingleNestedStructArrayCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)178 BlockSingleNestedStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
179 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
180 {
181 StructType& typeS = m_interface.allocStruct("S");
182 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
183 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
184 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
185
186 StructType& typeT = m_interface.allocStruct("T");
187 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
188 typeT.addMember("b", VarType(VarType(&typeS), 3));
189
190 UniformBlock& block = m_interface.allocBlock("Block");
191 block.addUniform(Uniform("s", VarType(&typeS), 0));
192 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
193 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
194 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
195 block.setFlags(layoutFlags);
196
197 if (numInstances > 0)
198 {
199 block.setInstanceName("block");
200 block.setArraySize(numInstances);
201 }
202 }
203 };
204
205 class BlockMultiBasicTypesCase : public UniformBlockCase
206 {
207 public:
BlockMultiBasicTypesCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 flagsA,deUint32 flagsB,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)208 BlockMultiBasicTypesCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
209 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
210 {
211 UniformBlock& blockA = m_interface.allocBlock("BlockA");
212 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
213 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
214 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
215 blockA.setInstanceName("blockA");
216 blockA.setFlags(flagsA);
217
218 UniformBlock& blockB = m_interface.allocBlock("BlockB");
219 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
220 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
221 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
222 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
223 blockB.setInstanceName("blockB");
224 blockB.setFlags(flagsB);
225
226 if (numInstances > 0)
227 {
228 blockA.setArraySize(numInstances);
229 blockB.setArraySize(numInstances);
230 }
231 }
232 };
233
234 class BlockMultiNestedStructCase : public UniformBlockCase
235 {
236 public:
BlockMultiNestedStructCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 flagsA,deUint32 flagsB,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)237 BlockMultiNestedStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
238 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
239 {
240 StructType& typeS = m_interface.allocStruct("S");
241 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
242 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
243 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
244
245 StructType& typeT = m_interface.allocStruct("T");
246 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
247 typeT.addMember("b", VarType(&typeS));
248 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
249
250 UniformBlock& blockA = m_interface.allocBlock("BlockA");
251 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
252 blockA.addUniform(Uniform("b", VarType(&typeS)));
253 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
254 blockA.setInstanceName("blockA");
255 blockA.setFlags(flagsA);
256
257 UniformBlock& blockB = m_interface.allocBlock("BlockB");
258 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
259 blockB.addUniform(Uniform("b", VarType(&typeT)));
260 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
261 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
262 blockB.setInstanceName("blockB");
263 blockB.setFlags(flagsB);
264
265 if (numInstances > 0)
266 {
267 blockA.setArraySize(numInstances);
268 blockB.setArraySize(numInstances);
269 }
270 }
271 };
272
273 class Block2LevelStructArrayCase : public UniformBlockCase
274 {
275 public:
Block2LevelStructArrayCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances,MatrixLoadFlags matrixLoadFlag)276 Block2LevelStructArrayCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances, MatrixLoadFlags matrixLoadFlag)
277 : UniformBlockCase (testCtx, name, description, bufferMode, matrixLoadFlag)
278 , m_layoutFlags (layoutFlags)
279 , m_numInstances (numInstances)
280 {
281 StructType& typeS = m_interface.allocStruct("S");
282 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
283 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 4));
284 typeS.addMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW));
285
286 UniformBlock& block = m_interface.allocBlock("Block");
287 block.addUniform(Uniform("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM)));
288 block.addUniform(Uniform("s", VarType(VarType(VarType(&typeS), 3), 2)));
289 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM)));
290 block.setFlags(m_layoutFlags);
291
292 if (m_numInstances > 0)
293 {
294 block.setInstanceName("block");
295 block.setArraySize(m_numInstances);
296 }
297 }
298
299 private:
300 deUint32 m_layoutFlags;
301 int m_numInstances;
302 };
303
304 class LinkByBindingCase : public UniformBlockCase
305 {
306 public:
LinkByBindingCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BufferMode bufferMode,int numInstances)307 LinkByBindingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, int numInstances)
308 : UniformBlockCase (testCtx, name, description, bufferMode, LOAD_FULL_MATRIX)
309 {
310 UniformBlock& blockA = m_interface.allocBlock("TestBlock");
311 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
312 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
313 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
314 blockA.setFlags(LAYOUT_STD140|DECLARE_VERTEX);
315
316 UniformBlock& blockB = m_interface.allocBlock("TestBlock");
317 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
318 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
319 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
320 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
321 blockB.setFlags(LAYOUT_STD140|DECLARE_FRAGMENT);
322
323 if (numInstances > 0)
324 {
325 blockA.setInstanceName("testBlock");
326 blockA.setArraySize(numInstances);
327 blockB.setInstanceName("testBlock");
328 blockB.setArraySize(numInstances);
329 }
330 }
331 };
332
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,tcu::TestContext & testCtx,const char * groupName,const char * description,UniformBlockCase::BufferMode bufferMode,deUint32 features,int numCases,deUint32 baseSeed)333 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
334 {
335 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName, description);
336 parentGroup->addChild(group);
337
338 baseSeed += (deUint32)testCtx.getCommandLine().getBaseSeed();
339
340 for (int ndx = 0; ndx < numCases; ndx++)
341 group->addChild(new RandomUniformBlockCase(testCtx, de::toString(ndx), "", bufferMode, features, (deUint32)ndx + baseSeed));
342 }
343
344 // UniformBlockTests
345
346 class UniformBlockTests : public tcu::TestCaseGroup
347 {
348 public:
349 UniformBlockTests (tcu::TestContext& testCtx);
350 ~UniformBlockTests (void);
351
352 void init (void);
353
354 private:
355 UniformBlockTests (const UniformBlockTests& other);
356 UniformBlockTests& operator= (const UniformBlockTests& other);
357 };
358
UniformBlockTests(tcu::TestContext & testCtx)359 UniformBlockTests::UniformBlockTests (tcu::TestContext& testCtx)
360 : TestCaseGroup(testCtx, "ubo", "Uniform Block tests")
361 {
362 }
363
~UniformBlockTests(void)364 UniformBlockTests::~UniformBlockTests (void)
365 {
366 }
367
init(void)368 void UniformBlockTests::init (void)
369 {
370 static const glu::DataType basicTypes[] =
371 {
372 glu::TYPE_FLOAT,
373 glu::TYPE_FLOAT_VEC2,
374 glu::TYPE_FLOAT_VEC3,
375 glu::TYPE_FLOAT_VEC4,
376 glu::TYPE_INT,
377 glu::TYPE_INT_VEC2,
378 glu::TYPE_INT_VEC3,
379 glu::TYPE_INT_VEC4,
380 glu::TYPE_UINT,
381 glu::TYPE_UINT_VEC2,
382 glu::TYPE_UINT_VEC3,
383 glu::TYPE_UINT_VEC4,
384 glu::TYPE_BOOL,
385 glu::TYPE_BOOL_VEC2,
386 glu::TYPE_BOOL_VEC3,
387 glu::TYPE_BOOL_VEC4,
388 glu::TYPE_FLOAT_MAT2,
389 glu::TYPE_FLOAT_MAT3,
390 glu::TYPE_FLOAT_MAT4,
391 glu::TYPE_FLOAT_MAT2X3,
392 glu::TYPE_FLOAT_MAT2X4,
393 glu::TYPE_FLOAT_MAT3X2,
394 glu::TYPE_FLOAT_MAT3X4,
395 glu::TYPE_FLOAT_MAT4X2,
396 glu::TYPE_FLOAT_MAT4X3,
397 glu::TYPE_UINT8,
398 glu::TYPE_UINT8_VEC2,
399 glu::TYPE_UINT8_VEC3,
400 glu::TYPE_UINT8_VEC4,
401 glu::TYPE_INT8,
402 glu::TYPE_INT8_VEC2,
403 glu::TYPE_INT8_VEC3,
404 glu::TYPE_INT8_VEC4,
405 glu::TYPE_UINT16,
406 glu::TYPE_UINT16_VEC2,
407 glu::TYPE_UINT16_VEC3,
408 glu::TYPE_UINT16_VEC4,
409 glu::TYPE_INT16,
410 glu::TYPE_INT16_VEC2,
411 glu::TYPE_INT16_VEC3,
412 glu::TYPE_INT16_VEC4,
413 glu::TYPE_FLOAT16,
414 glu::TYPE_FLOAT16_VEC2,
415 glu::TYPE_FLOAT16_VEC3,
416 glu::TYPE_FLOAT16_VEC4,
417 };
418
419 static const struct
420 {
421 const std::string name;
422 deUint32 flags;
423 } precisionFlags[] =
424 {
425 // TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision?
426 { "lowp", PRECISION_LOW },
427 { "mediump", PRECISION_MEDIUM },
428 { "highp", PRECISION_HIGH }
429 };
430
431 static const struct
432 {
433 const char* name;
434 deUint32 flags;
435 } layoutFlags[] =
436 {
437 { "std140", LAYOUT_STD140 },
438 { "std430", LAYOUT_STD430 },
439 { "scalar", LAYOUT_SCALAR }
440 };
441
442 static const struct
443 {
444 const std::string name;
445 deUint32 flags;
446 } matrixFlags[] =
447 {
448 { "row_major", LAYOUT_ROW_MAJOR },
449 { "column_major", LAYOUT_COLUMN_MAJOR }
450 };
451
452 static const struct
453 {
454 const char* name;
455 UniformBlockCase::BufferMode mode;
456 } bufferModes[] =
457 {
458 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
459 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE }
460 };
461
462 // ubo.2_level_array
463 {
464 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level basic array variable in single buffer");
465 addChild(nestedArrayGroup);
466
467 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
468 {
469 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
470
471 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
472 {
473 const glu::DataType type = basicTypes[basicTypeNdx];
474 const char* const typeName = glu::getDataTypeName(type);
475 const int childSize = 4;
476 const int parentSize = 3;
477 const VarType childType (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize);
478 const VarType parentType (childType, parentSize);
479
480 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
481
482 if (glu::isDataTypeMatrix(type))
483 {
484 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
485 createBlockBasicTypeCases(*layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
486 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
487 }
488 }
489 nestedArrayGroup->addChild(layoutGroup.release());
490 }
491 }
492
493 // ubo.3_level_array
494 {
495 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
496 addChild(nestedArrayGroup);
497
498 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
499 {
500 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
501
502 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
503 {
504 const glu::DataType type = basicTypes[basicTypeNdx];
505 const char* const typeName = glu::getDataTypeName(type);
506 const int childSize0 = 2;
507 const int childSize1 = 4;
508 const int parentSize = 3;
509 const VarType childType0 (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize0);
510 const VarType childType1 (childType0, childSize1);
511 const VarType parentType (childType1, parentSize);
512
513 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
514
515 if (glu::isDataTypeMatrix(type))
516 {
517 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
518 createBlockBasicTypeCases(*layoutGroup, m_testCtx, (std::string(matrixFlags[matFlagNdx].name) + "_" + typeName),
519 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
520 }
521 }
522 nestedArrayGroup->addChild(layoutGroup.release());
523 }
524 }
525
526 // ubo.2_level_struct_array
527 {
528 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one uniform block");
529 addChild(structArrayArrayGroup);
530
531 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
532 {
533 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
534 structArrayArrayGroup->addChild(modeGroup);
535
536 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
537 {
538 for (int isArray = 0; isArray < 2; isArray++)
539 {
540 std::string baseName = layoutFlags[layoutFlagNdx].name;
541 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
542
543 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
544 continue; // Doesn't make sense to add this variant.
545
546 if (isArray)
547 baseName += "_instance_array";
548
549 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex"), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
550 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment"), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
551 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both"), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
552 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex_comp_access"), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
553 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_fragment_comp_access"), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
554 modeGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_both_comp_access"), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
555 }
556 }
557 }
558 }
559
560 // ubo.single_basic_type
561 {
562 tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
563 addChild(singleBasicTypeGroup);
564
565 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
566 {
567 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
568
569 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
570 {
571 glu::DataType type = basicTypes[basicTypeNdx];
572 const char* const typeName = glu::getDataTypeName(type);
573
574 if (!dataTypeSupportsPrecisionModifier(type))
575 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName, VarType(type, 0), layoutFlags[layoutFlagNdx].flags);
576 }
577
578 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
579 {
580 de::MovePtr<tcu::TestCaseGroup> precGroup(new tcu::TestCaseGroup(m_testCtx, precisionFlags[precNdx].name.c_str(), ""));
581
582 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
583 {
584 glu::DataType type = basicTypes[basicTypeNdx];
585 const char* const typeName = glu::getDataTypeName(type);
586
587 if (dataTypeSupportsPrecisionModifier(type))
588 createBlockBasicTypeCases(*precGroup, m_testCtx, typeName,
589 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
590
591 if (glu::isDataTypeMatrix(type))
592 {
593 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
594 {
595 createBlockBasicTypeCases(*precGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
596 VarType(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags);
597
598 }
599 }
600 }
601 layoutGroup->addChild(precGroup.release());
602 }
603 singleBasicTypeGroup->addChild(layoutGroup.release());
604 }
605 }
606
607 // ubo.single_basic_array
608 {
609 tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
610 addChild(singleBasicArrayGroup);
611
612 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
613 {
614 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
615
616 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
617 {
618 glu::DataType type = basicTypes[basicTypeNdx];
619 const char* const typeName = glu::getDataTypeName(type);
620 const int arraySize = 3;
621
622 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName,
623 VarType(VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), arraySize),
624 layoutFlags[layoutFlagNdx].flags);
625
626 if (glu::isDataTypeMatrix(type))
627 {
628 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
629 createBlockBasicTypeCases(*layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
630 VarType(VarType(type, PRECISION_HIGH), arraySize),
631 layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
632 }
633 }
634 singleBasicArrayGroup->addChild(layoutGroup.release());
635 }
636 }
637
638 // ubo.single_struct
639 {
640 tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
641 addChild(singleStructGroup);
642
643 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
644 {
645 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
646 singleStructGroup->addChild(modeGroup);
647
648 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
649 {
650 for (int isArray = 0; isArray < 2; isArray++)
651 {
652 std::string baseName = layoutFlags[layoutFlagNdx].name;
653 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
654
655 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
656 continue; // Doesn't make sense to add this variant.
657
658 if (isArray)
659 baseName += "_instance_array";
660
661 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
662 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
663 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
664 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
665 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
666 modeGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
667 }
668 }
669 }
670 }
671
672 // ubo.single_struct_array
673 {
674 tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
675 addChild(singleStructArrayGroup);
676
677 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
678 {
679 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
680 singleStructArrayGroup->addChild(modeGroup);
681
682 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
683 {
684 for (int isArray = 0; isArray < 2; isArray++)
685 {
686 std::string baseName = layoutFlags[layoutFlagNdx].name;
687 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
688
689 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
690 continue; // Doesn't make sense to add this variant.
691
692 if (isArray)
693 baseName += "_instance_array";
694
695 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
696 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
697 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
698 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
699 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
700 modeGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
701 }
702 }
703 }
704 }
705
706 // ubo.single_nested_struct
707 {
708 tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
709 addChild(singleNestedStructGroup);
710
711 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
712 {
713 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
714 singleNestedStructGroup->addChild(modeGroup);
715
716 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
717 {
718 for (int isArray = 0; isArray < 2; isArray++)
719 {
720 std::string baseName = layoutFlags[layoutFlagNdx].name;
721 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
722
723 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
724 continue; // Doesn't make sense to add this variant.
725
726 if (isArray)
727 baseName += "_instance_array";
728
729 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
730 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
731 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
732 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
733 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
734 modeGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
735 }
736 }
737 }
738 }
739
740 // ubo.single_nested_struct_array
741 {
742 tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
743 addChild(singleNestedStructArrayGroup);
744
745 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
746 {
747 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
748 singleNestedStructArrayGroup->addChild(modeGroup);
749
750 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
751 {
752 for (int isArray = 0; isArray < 2; isArray++)
753 {
754 std::string baseName = layoutFlags[layoutFlagNdx].name;
755 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
756
757 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
758 continue; // Doesn't make sense to add this variant.
759
760 if (isArray)
761 baseName += "_instance_array";
762
763 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
764 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
765 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
766 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
767 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
768 modeGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
769 }
770 }
771 }
772 }
773
774 // ubo.instance_array_basic_type
775 {
776 tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
777 addChild(instanceArrayBasicTypeGroup);
778
779 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
780 {
781 de::MovePtr<tcu::TestCaseGroup> layoutGroup(new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, ""));
782
783 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
784 {
785 glu::DataType type = basicTypes[basicTypeNdx];
786 const char* const typeName = glu::getDataTypeName(type);
787 const int numInstances = 3;
788
789 createBlockBasicTypeCases(*layoutGroup, m_testCtx, typeName,
790 VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH),
791 layoutFlags[layoutFlagNdx].flags, numInstances);
792
793 if (glu::isDataTypeMatrix(type))
794 {
795 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
796 createBlockBasicTypeCases(*layoutGroup, m_testCtx, matrixFlags[matFlagNdx].name + "_" + typeName,
797 VarType(type, PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags,
798 numInstances);
799 }
800 }
801 instanceArrayBasicTypeGroup->addChild(layoutGroup.release());
802 }
803 }
804
805 // ubo.multi_basic_types
806 {
807 tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
808 addChild(multiBasicTypesGroup);
809
810 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
811 {
812 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
813 multiBasicTypesGroup->addChild(modeGroup);
814
815 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
816 {
817 for (int isArray = 0; isArray < 2; isArray++)
818 {
819 std::string baseName = layoutFlags[layoutFlagNdx].name;
820 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
821
822 if (isArray)
823 baseName += "_instance_array";
824
825 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
826 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
827 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
828 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
829 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
830 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
831 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
832 modeGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_mixed_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
833 }
834 }
835 }
836 }
837
838 // ubo.multi_nested_struct
839 {
840 tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
841 addChild(multiNestedStructGroup);
842
843 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
844 {
845 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
846 multiNestedStructGroup->addChild(modeGroup);
847
848 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
849 {
850 for (int isArray = 0; isArray < 2; isArray++)
851 {
852 std::string baseName = layoutFlags[layoutFlagNdx].name;
853 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
854
855 if (isArray)
856 baseName += "_instance_array";
857
858 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
859 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_fragment", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
860 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_both", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
861 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_mixed", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_FULL_MATRIX));
862 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
863 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_fragment_comp_access", "", baseFlags|DECLARE_FRAGMENT, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
864 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_both_comp_access", "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
865 modeGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_mixed_comp_access", "", baseFlags|DECLARE_VERTEX, baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0, LOAD_MATRIX_COMPONENTS));
866 }
867 }
868 }
869 }
870
871 // .link_by_binding
872 {
873 tcu::TestCaseGroup* linkByBindingGroup = new tcu::TestCaseGroup(m_testCtx, "link_by_binding", "Blocks with same name but different binding");
874 addChild(linkByBindingGroup);
875
876 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_single_instance", "", UniformBlockCase::BUFFERMODE_SINGLE, 0));
877 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "single_buf_instance_array", "", UniformBlockCase::BUFFERMODE_SINGLE, 2));
878 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_single_instance", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 0));
879 linkByBindingGroup->addChild(new LinkByBindingCase(m_testCtx, "per_block_buf_instance_array", "", UniformBlockCase::BUFFERMODE_PER_BLOCK, 2));
880 }
881
882 // ubo.random
883 {
884 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
885 const deUint32 allLayouts = FEATURE_STD140_LAYOUT;
886 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES;
887 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
888 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT;
889 const deUint32 allFeatures = ~FEATURE_OUT_OF_ORDER_OFFSETS & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE
890 & ~FEATURE_STD430_LAYOUT & ~FEATURE_SCALAR_LAYOUT & ~FEATURE_DESCRIPTOR_INDEXING; // OOO offsets handled in a dedicated case group
891 const deUint32 allScalar = ~allLayouts & ~FEATURE_16BIT_STORAGE & ~FEATURE_8BIT_STORAGE & ~FEATURE_DESCRIPTOR_INDEXING;
892 const deUint32 descriptorIndexing = FEATURE_STD140_LAYOUT | FEATURE_STD430_LAYOUT | FEATURE_SCALAR_LAYOUT | FEATURE_DESCRIPTOR_INDEXING | allShaders | allBasicTypes | unused | matFlags;
893
894 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
895 addChild(randomGroup);
896
897 for (int i = 0; i < 3; ++i)
898 {
899
900 tcu::TestCaseGroup* group = randomGroup;
901 if (i == 1)
902 {
903 group = new tcu::TestCaseGroup(m_testCtx, "16bit", "16bit storage");
904 randomGroup->addChild(group);
905 }
906 if (i == 2)
907 {
908 group = new tcu::TestCaseGroup(m_testCtx, "8bit", "8bit storage");
909 randomGroup->addChild(group);
910 }
911 const deUint32 use16BitStorage = i == 1 ? FEATURE_16BIT_STORAGE : 0;
912 const deUint32 use8BitStorage = i == 2 ? FEATURE_8BIT_STORAGE : 0;
913
914 // Basic types.
915 createRandomCaseGroup(group, m_testCtx, "scalar_types", "Scalar types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused, 25, 0);
916 createRandomCaseGroup(group, m_testCtx, "vector_types", "Scalar and vector types only, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|FEATURE_VECTORS, 25, 25);
917 createRandomCaseGroup(group, m_testCtx, "basic_types", "All basic types, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags, 25, 50);
918 createRandomCaseGroup(group, m_testCtx, "basic_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS, 25, 50);
919
920 createRandomCaseGroup(group, m_testCtx, "basic_instance_arrays", "Basic instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_INSTANCE_ARRAYS, 25, 75);
921 createRandomCaseGroup(group, m_testCtx, "nested_structs", "Nested structs, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS, 25, 100);
922 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS, 25, 150);
923 createRandomCaseGroup(group, m_testCtx, "nested_structs_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS, 25, 125);
924 createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays_instance_arrays", "Nested structs, instance arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS, 25, 175);
925
926 createRandomCaseGroup(group, m_testCtx, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allFeatures, 50, 200);
927 createRandomCaseGroup(group, m_testCtx, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, use8BitStorage|use16BitStorage|allFeatures, 50, 250);
928
929 createRandomCaseGroup(group, m_testCtx, "all_out_of_order_offsets", "All random features, out of order member offsets", UniformBlockCase::BUFFERMODE_PER_BLOCK, use8BitStorage|use16BitStorage|allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS, 50, 300);
930 createRandomCaseGroup(group, m_testCtx, "scalar", "VK_EXT_scalar_block_layout", UniformBlockCase::BUFFERMODE_SINGLE, use8BitStorage|use16BitStorage|allScalar, 100, deInt32Hash(313));
931 createRandomCaseGroup(group, m_testCtx, "descriptor_indexing", "VK_EXT_descriptor_indexing", UniformBlockCase::BUFFERMODE_SINGLE, use8BitStorage|use16BitStorage|descriptorIndexing, 50, 123);
932 }
933 }
934 }
935
936 } // anonymous
937
createTests(tcu::TestContext & testCtx)938 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
939 {
940 return new UniformBlockTests(testCtx);
941 }
942
943 } // ubo
944 } // vkt
945