1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2016 Google Inc.
6 * Copyright (c) 2016 The Khronos Group Inc.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Uniform block tests.
23 */ /*-------------------------------------------------------------------*/
25 #include "glcUniformBlockTests.hpp"
26 #include "deRandom.hpp"
27 #include "deStringUtil.hpp"
28 #include "glcUniformBlockCase.hpp"
29 #include "glwEnums.hpp"
30 #include "glwFunctions.hpp"
31 #include "tcuCommandLine.hpp"
32 #include "tcuTestLog.hpp"
45 FEATURE_VECTORS = (1 << 0),
46 FEATURE_MATRICES = (1 << 1),
47 FEATURE_ARRAYS = (1 << 2),
48 FEATURE_STRUCTS = (1 << 3),
49 FEATURE_NESTED_STRUCTS = (1 << 4),
50 FEATURE_INSTANCE_ARRAYS = (1 << 5),
51 FEATURE_VERTEX_BLOCKS = (1 << 6),
52 FEATURE_FRAGMENT_BLOCKS = (1 << 7),
53 FEATURE_SHARED_BLOCKS = (1 << 8),
54 FEATURE_UNUSED_UNIFORMS = (1 << 9),
55 FEATURE_UNUSED_MEMBERS = (1 << 10),
56 FEATURE_PACKED_LAYOUT = (1 << 11),
57 FEATURE_SHARED_LAYOUT = (1 << 12),
58 FEATURE_STD140_LAYOUT = (1 << 13),
59 FEATURE_MATRIX_LAYOUT = (1 << 14) //!< Matrix layout flags.
62 class RandomUniformBlockCase : public UniformBlockCase
65 RandomUniformBlockCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
66 BufferMode bufferMode, deUint32 features, deUint32 seed);
71 void generateBlock(de::Random& rnd, deUint32 layoutFlags);
72 void generateUniform(de::Random& rnd, UniformBlock& block);
73 VarType generateType(de::Random& rnd, int typeDepth, bool arrayOk);
76 int m_maxVertexBlocks;
77 int m_maxFragmentBlocks;
78 int m_maxSharedBlocks;
82 int m_maxBlockMembers;
83 int m_maxStructMembers;
91 RandomUniformBlockCase::RandomUniformBlockCase(Context& context, const char* name, const char* description,
92 glu::GLSLVersion glslVersion, BufferMode bufferMode, deUint32 features,
94 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
95 , m_features(features)
96 , m_maxVertexBlocks((features & FEATURE_VERTEX_BLOCKS) ? 4 : 0)
97 , m_maxFragmentBlocks((features & FEATURE_FRAGMENT_BLOCKS) ? 4 : 0)
98 , m_maxSharedBlocks((features & FEATURE_SHARED_BLOCKS) ? 4 : 0)
99 , m_maxInstances((features & FEATURE_INSTANCE_ARRAYS) ? 3 : 0)
100 , m_maxArrayLength((features & FEATURE_ARRAYS) ? 8 : 0)
101 , m_maxStructDepth((features & FEATURE_STRUCTS) ? 2 : 0)
102 , m_maxBlockMembers(5)
103 , m_maxStructMembers(4)
111 void RandomUniformBlockCase::init(void)
113 de::Random rnd(m_seed);
115 int numShared = m_maxSharedBlocks > 0 ? rnd.getInt(1, m_maxSharedBlocks) : 0;
116 int numVtxBlocks = m_maxVertexBlocks - numShared > 0 ? rnd.getInt(1, m_maxVertexBlocks - numShared) : 0;
117 int numFragBlocks = m_maxFragmentBlocks - numShared > 0 ? rnd.getInt(1, m_maxFragmentBlocks - numShared) : 0;
119 for (int ndx = 0; ndx < numShared; ndx++)
120 generateBlock(rnd, DECLARE_VERTEX | DECLARE_FRAGMENT);
122 for (int ndx = 0; ndx < numVtxBlocks; ndx++)
123 generateBlock(rnd, DECLARE_VERTEX);
125 for (int ndx = 0; ndx < numFragBlocks; ndx++)
126 generateBlock(rnd, DECLARE_FRAGMENT);
129 void RandomUniformBlockCase::generateBlock(de::Random& rnd, deUint32 layoutFlags)
131 DE_ASSERT(m_blockNdx <= 'z' - 'a');
133 const float instanceArrayWeight = 0.3f;
134 UniformBlock& block = m_interface.allocBlock((string("Block") + (char)('A' + m_blockNdx)).c_str());
135 int numInstances = (m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, m_maxInstances) : 0;
136 int numUniforms = rnd.getInt(1, m_maxBlockMembers);
138 if (numInstances > 0)
139 block.setArraySize(numInstances);
141 if (numInstances > 0 || rnd.getBool())
142 block.setInstanceName((string("block") + (char)('A' + m_blockNdx)).c_str());
144 // Layout flag candidates.
145 vector<deUint32> layoutFlagCandidates;
146 layoutFlagCandidates.push_back(0);
147 if (m_features & FEATURE_PACKED_LAYOUT)
148 layoutFlagCandidates.push_back(LAYOUT_SHARED);
149 if ((m_features & FEATURE_SHARED_LAYOUT) && ((layoutFlags & DECLARE_BOTH) != DECLARE_BOTH))
150 layoutFlagCandidates.push_back(LAYOUT_PACKED); // \note packed layout can only be used in a single shader stage.
151 if (m_features & FEATURE_STD140_LAYOUT)
152 layoutFlagCandidates.push_back(LAYOUT_STD140);
154 layoutFlags |= rnd.choose<deUint32>(layoutFlagCandidates.begin(), layoutFlagCandidates.end());
156 if (m_features & FEATURE_MATRIX_LAYOUT)
158 static const deUint32 matrixCandidates[] = { 0, LAYOUT_ROW_MAJOR, LAYOUT_COLUMN_MAJOR };
160 rnd.choose<deUint32>(&matrixCandidates[0], &matrixCandidates[DE_LENGTH_OF_ARRAY(matrixCandidates)]);
163 block.setFlags(layoutFlags);
165 for (int ndx = 0; ndx < numUniforms; ndx++)
166 generateUniform(rnd, block);
171 static std::string genName(char first, char last, int ndx)
173 std::string str = "";
174 int alphabetLen = last - first + 1;
176 while (ndx > alphabetLen)
178 str.insert(str.begin(), (char)(first + ((ndx - 1) % alphabetLen)));
179 ndx = ((ndx - 1) / alphabetLen);
182 str.insert(str.begin(), (char)(first + (ndx % (alphabetLen + 1)) - 1));
187 void RandomUniformBlockCase::generateUniform(de::Random& rnd, UniformBlock& block)
189 const float unusedVtxWeight = 0.15f;
190 const float unusedFragWeight = 0.15f;
191 bool unusedOk = (m_features & FEATURE_UNUSED_UNIFORMS) != 0;
193 std::string name = genName('a', 'z', m_uniformNdx);
194 VarType type = generateType(rnd, 0, true);
196 flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? UNUSED_VERTEX : 0;
197 flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? UNUSED_FRAGMENT : 0;
199 block.addUniform(Uniform(name.c_str(), type, flags));
204 VarType RandomUniformBlockCase::generateType(de::Random& rnd, int typeDepth, bool arrayOk)
206 const float structWeight = 0.1f;
207 const float arrayWeight = 0.1f;
209 if (typeDepth < m_maxStructDepth && rnd.getFloat() < structWeight)
211 const float unusedVtxWeight = 0.15f;
212 const float unusedFragWeight = 0.15f;
213 bool unusedOk = (m_features & FEATURE_UNUSED_MEMBERS) != 0;
214 vector<VarType> memberTypes;
215 int numMembers = rnd.getInt(1, m_maxStructMembers);
217 // Generate members first so nested struct declarations are in correct order.
218 for (int ndx = 0; ndx < numMembers; ndx++)
219 memberTypes.push_back(generateType(rnd, typeDepth + 1, true));
221 StructType& structType = m_interface.allocStruct((string("s") + genName('A', 'Z', m_structNdx)).c_str());
224 DE_ASSERT(numMembers <= 'Z' - 'A');
225 for (int ndx = 0; ndx < numMembers; ndx++)
229 flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? UNUSED_VERTEX : 0;
230 flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? UNUSED_FRAGMENT : 0;
232 structType.addMember((string("m") + (char)('A' + ndx)).c_str(), memberTypes[ndx], flags);
235 return VarType(&structType);
237 else if (m_maxArrayLength > 0 && arrayOk && rnd.getFloat() < arrayWeight)
239 int arrayLength = rnd.getInt(1, m_maxArrayLength);
240 VarType elementType = generateType(rnd, typeDepth, false /* nested arrays are not allowed */);
241 return VarType(elementType, arrayLength);
245 vector<glu::DataType> typeCandidates;
247 typeCandidates.push_back(glu::TYPE_FLOAT);
248 typeCandidates.push_back(glu::TYPE_INT);
249 typeCandidates.push_back(glu::TYPE_UINT);
250 typeCandidates.push_back(glu::TYPE_BOOL);
252 if (m_features & FEATURE_VECTORS)
254 typeCandidates.push_back(glu::TYPE_FLOAT_VEC2);
255 typeCandidates.push_back(glu::TYPE_FLOAT_VEC3);
256 typeCandidates.push_back(glu::TYPE_FLOAT_VEC4);
257 typeCandidates.push_back(glu::TYPE_INT_VEC2);
258 typeCandidates.push_back(glu::TYPE_INT_VEC3);
259 typeCandidates.push_back(glu::TYPE_INT_VEC4);
260 typeCandidates.push_back(glu::TYPE_UINT_VEC2);
261 typeCandidates.push_back(glu::TYPE_UINT_VEC3);
262 typeCandidates.push_back(glu::TYPE_UINT_VEC4);
263 typeCandidates.push_back(glu::TYPE_BOOL_VEC2);
264 typeCandidates.push_back(glu::TYPE_BOOL_VEC3);
265 typeCandidates.push_back(glu::TYPE_BOOL_VEC4);
268 if (m_features & FEATURE_MATRICES)
270 typeCandidates.push_back(glu::TYPE_FLOAT_MAT2);
271 typeCandidates.push_back(glu::TYPE_FLOAT_MAT2X3);
272 typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X2);
273 typeCandidates.push_back(glu::TYPE_FLOAT_MAT3);
274 typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X4);
275 typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X2);
276 typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X3);
277 typeCandidates.push_back(glu::TYPE_FLOAT_MAT4);
280 glu::DataType type = rnd.choose<glu::DataType>(typeCandidates.begin(), typeCandidates.end());
283 if (!glu::isDataTypeBoolOrBVec(type))
286 static const deUint32 precisionCandidates[] = { PRECISION_LOW, PRECISION_MEDIUM, PRECISION_HIGH };
287 flags |= rnd.choose<deUint32>(&precisionCandidates[0],
288 &precisionCandidates[DE_LENGTH_OF_ARRAY(precisionCandidates)]);
291 return VarType(type, flags);
295 class BlockBasicTypeCase : public UniformBlockCase
298 BlockBasicTypeCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
299 const VarType& type, deUint32 layoutFlags, int numInstances)
300 : UniformBlockCase(context, name, description, glslVersion, BUFFERMODE_PER_BLOCK)
302 UniformBlock& block = m_interface.allocBlock("Block");
303 block.addUniform(Uniform("var", type, 0));
304 block.setFlags(layoutFlags);
306 if (numInstances > 0)
308 block.setArraySize(numInstances);
309 block.setInstanceName("block");
314 static void createRandomCaseGroup(tcu::TestCaseGroup* parentGroup, Context& context, const char* groupName,
315 const char* description, glu::GLSLVersion glslVersion,
316 UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases,
319 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
320 parentGroup->addChild(group);
322 baseSeed += (deUint32)context.getTestContext().getCommandLine().getBaseSeed();
324 for (int ndx = 0; ndx < numCases; ndx++)
325 group->addChild(new RandomUniformBlockCase(context, de::toString(ndx).c_str(), "", glslVersion, bufferMode,
326 features, (deUint32)deInt32Hash(ndx + baseSeed)));
329 class BlockSingleStructCase : public UniformBlockCase
332 BlockSingleStructCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
333 deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
334 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
335 , m_layoutFlags(layoutFlags)
336 , m_numInstances(numInstances)
342 StructType& typeS = m_interface.allocStruct("S");
343 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH); // First member is unused.
344 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
345 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
347 UniformBlock& block = m_interface.allocBlock("Block");
348 block.addUniform(Uniform("s", VarType(&typeS), 0));
349 block.setFlags(m_layoutFlags);
351 if (m_numInstances > 0)
353 block.setInstanceName("block");
354 block.setArraySize(m_numInstances);
359 deUint32 m_layoutFlags;
363 class BlockSingleStructArrayCase : public UniformBlockCase
366 BlockSingleStructArrayCase(Context& context, const char* name, const char* description,
367 glu::GLSLVersion glslVersion, deUint32 layoutFlags, BufferMode bufferMode,
369 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
370 , m_layoutFlags(layoutFlags)
371 , m_numInstances(numInstances)
377 StructType& typeS = m_interface.allocStruct("S");
378 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
379 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
380 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
382 UniformBlock& block = m_interface.allocBlock("Block");
383 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
384 block.addUniform(Uniform("s", VarType(VarType(&typeS), 3)));
385 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
386 block.setFlags(m_layoutFlags);
388 if (m_numInstances > 0)
390 block.setInstanceName("block");
391 block.setArraySize(m_numInstances);
396 deUint32 m_layoutFlags;
400 class BlockSingleNestedStructCase : public UniformBlockCase
403 BlockSingleNestedStructCase(Context& context, const char* name, const char* description,
404 glu::GLSLVersion glslVersion, deUint32 layoutFlags, BufferMode bufferMode,
406 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
407 , m_layoutFlags(layoutFlags)
408 , m_numInstances(numInstances)
414 StructType& typeS = m_interface.allocStruct("S");
415 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
416 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM), 4));
417 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
419 StructType& typeT = m_interface.allocStruct("T");
420 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
421 typeT.addMember("b", VarType(&typeS));
423 UniformBlock& block = m_interface.allocBlock("Block");
424 block.addUniform(Uniform("s", VarType(&typeS), 0));
425 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
426 block.addUniform(Uniform("t", VarType(&typeT), 0));
427 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
428 block.setFlags(m_layoutFlags);
430 if (m_numInstances > 0)
432 block.setInstanceName("block");
433 block.setArraySize(m_numInstances);
438 deUint32 m_layoutFlags;
442 class BlockSingleNestedStructArrayCase : public UniformBlockCase
445 BlockSingleNestedStructArrayCase(Context& context, const char* name, const char* description,
446 glu::GLSLVersion glslVersion, deUint32 layoutFlags, BufferMode bufferMode,
448 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
449 , m_layoutFlags(layoutFlags)
450 , m_numInstances(numInstances)
456 StructType& typeS = m_interface.allocStruct("S");
457 typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
458 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
459 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH);
461 StructType& typeT = m_interface.allocStruct("T");
462 typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
463 typeT.addMember("b", VarType(VarType(&typeS), 3));
465 UniformBlock& block = m_interface.allocBlock("Block");
466 block.addUniform(Uniform("s", VarType(&typeS), 0));
467 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), UNUSED_BOTH));
468 block.addUniform(Uniform("t", VarType(VarType(&typeT), 2), 0));
469 block.addUniform(Uniform("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
470 block.setFlags(m_layoutFlags);
472 if (m_numInstances > 0)
474 block.setInstanceName("block");
475 block.setArraySize(m_numInstances);
480 deUint32 m_layoutFlags;
484 class BlockMultiBasicTypesCase : public UniformBlockCase
487 BlockMultiBasicTypesCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
488 deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode, int numInstances)
489 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
492 , m_numInstances(numInstances)
498 UniformBlock& blockA = m_interface.allocBlock("BlockA");
499 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
500 blockA.addUniform(Uniform("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
501 blockA.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
502 blockA.setInstanceName("blockA");
503 blockA.setFlags(m_flagsA);
505 UniformBlock& blockB = m_interface.allocBlock("BlockB");
506 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
507 blockB.addUniform(Uniform("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
508 blockB.addUniform(Uniform("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), UNUSED_BOTH));
509 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
510 blockB.setInstanceName("blockB");
511 blockB.setFlags(m_flagsB);
513 if (m_numInstances > 0)
515 blockA.setArraySize(m_numInstances);
516 blockB.setArraySize(m_numInstances);
526 class BlockMultiNestedStructCase : public UniformBlockCase
529 BlockMultiNestedStructCase(Context& context, const char* name, const char* description,
530 glu::GLSLVersion glslVersion, deUint32 flagsA, deUint32 flagsB, BufferMode bufferMode,
532 : UniformBlockCase(context, name, description, glslVersion, bufferMode)
535 , m_numInstances(numInstances)
541 StructType& typeS = m_interface.allocStruct("S");
542 typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_LOW));
543 typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 4));
544 typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
546 StructType& typeT = m_interface.allocStruct("T");
547 typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), UNUSED_BOTH);
548 typeT.addMember("b", VarType(&typeS));
549 typeT.addMember("c", VarType(glu::TYPE_BOOL_VEC4, 0));
551 UniformBlock& blockA = m_interface.allocBlock("BlockA");
552 blockA.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
553 blockA.addUniform(Uniform("b", VarType(&typeS)));
554 blockA.addUniform(Uniform("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), UNUSED_BOTH));
555 blockA.setInstanceName("blockA");
556 blockA.setFlags(m_flagsA);
558 UniformBlock& blockB = m_interface.allocBlock("BlockB");
559 blockB.addUniform(Uniform("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
560 blockB.addUniform(Uniform("b", VarType(&typeT)));
561 blockB.addUniform(Uniform("c", VarType(glu::TYPE_BOOL_VEC4, 0), UNUSED_BOTH));
562 blockB.addUniform(Uniform("d", VarType(glu::TYPE_BOOL, 0)));
563 blockB.setInstanceName("blockB");
564 blockB.setFlags(m_flagsB);
566 if (m_numInstances > 0)
568 blockA.setArraySize(m_numInstances);
569 blockB.setArraySize(m_numInstances);
579 class UniformBlockPrecisionMatching : public TestCase
582 UniformBlockPrecisionMatching(Context& context, glu::GLSLVersion glslVersion)
583 : TestCase(context, "precision_matching", ""), m_glslVersion(glslVersion)
587 IterateResult iterate(void)
589 std::string vs1("layout (std140) uniform Data { lowp float x; } myData;\n"
591 " gl_Position = vec4(myData.x, 0.0, 0.0, 1.0);\n"
593 std::string fs1("precision highp float;\n"
595 "layout (std140) uniform Data { float x; } myData;\n"
597 " color = vec4(myData.x);\n"
600 std::string vs2("layout (std140) uniform Data { highp int x; mediump int y; } myData;\n"
602 " gl_Position = vec4(float(myData.x), 0.0, 0.0, 1.0);\n"
604 std::string fs2("precision highp float;\n"
606 "layout (std140) uniform Data { mediump int x; highp int y; } myData;\n"
608 " color = vec4(float(myData.y));\n"
611 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
612 if (!Link(vs1, fs1) || !Link(vs2, fs2))
613 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
617 bool Link(const std::string& vs, const std::string& fs)
619 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
620 const glw::GLuint p = gl.createProgram();
621 const std::string version = glu::getGLSLVersionDeclaration(m_glslVersion);
626 const std::string& body;
628 } shaderDefinition[] = { { "VS", vs, GL_VERTEX_SHADER }, { "FS", fs, GL_FRAGMENT_SHADER } };
630 for (unsigned int index = 0; index < 2; ++index)
632 std::string shaderSource = version + "\n" + shaderDefinition[index].body;
633 const char* shaderSourcePtr = shaderSource.c_str();
635 glw::GLuint sh = gl.createShader(shaderDefinition[index].type);
636 gl.attachShader(p, sh);
638 gl.shaderSource(sh, 1, &shaderSourcePtr, NULL);
639 gl.compileShader(sh);
642 gl.getShaderiv(sh, GL_COMPILE_STATUS, &status);
643 if (status == GL_FALSE)
646 gl.getShaderiv(sh, GL_INFO_LOG_LENGTH, &length);
649 std::vector<glw::GLchar> log(length);
650 gl.getShaderInfoLog(sh, length, NULL, &log[0]);
651 m_context.getTestContext().getLog() << tcu::TestLog::Message << shaderDefinition[index].name
652 << " compilation should succed. Info Log:\n"
653 << &log[0] << tcu::TestLog::EndMessage;
664 gl.getProgramiv(p, GL_LINK_STATUS, &status);
665 if (status == GL_FALSE)
667 glw::GLchar log[1024];
668 gl.getProgramInfoLog(p, sizeof(log), NULL, log);
669 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Link operation should succed. Info Log:\n"
670 << log << tcu::TestLog::EndMessage;
679 glu::GLSLVersion m_glslVersion;
682 class UniformBlockNameMatching : public TestCase
685 UniformBlockNameMatching(Context& context, glu::GLSLVersion glslVersion)
686 : TestCase(context, "name_matching", ""), m_glslVersion(glslVersion)
690 IterateResult iterate(void)
692 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
694 std::string vs1("precision highp float;\n"
695 "layout (std140) uniform Data { vec4 v; };\n"
697 " gl_Position = v;\n"
699 std::string fs1("precision highp float;\n"
701 "layout (std140) uniform Data { vec4 v; } myData;\n"
703 " color = vec4(myData.v);\n"
706 // check if link error is generated when one of matched blocks has instance name and other doesn't
707 if (!Test(vs1, fs1, GL_FALSE))
710 std::string vs2("precision highp float;\n"
711 "uniform Data { vec4 v; };\n"
713 " gl_Position = v;\n"
715 std::string fs2("precision highp float;\n"
717 "uniform Data { vec4 v; };\n"
722 // check if linking succeeds when both matched blocks are lacking an instance name
723 if (!Test(vs2, fs2, GL_TRUE))
726 std::string vs3("precision highp float;\n"
727 "layout (std140) uniform Data { vec4 v; } a;\n"
729 " gl_Position = a.v;\n"
731 std::string fs3("precision highp float;\n"
733 "layout (std140) uniform Data { vec4 v; } b;\n"
738 // check if linking succeeds when both matched blocks are lacking an instance name
739 if (!Test(vs3, fs3, GL_TRUE))
742 std::string vs4("precision highp float;\n"
743 "layout (std140) uniform Data { float f; };\n"
745 " gl_Position = vec4(f);\n"
747 std::string fs4("precision highp float;\n"
751 " color = vec4(f);\n"
754 // check if link error is generated when the same name is used for block and non-block uniform
755 if (!Test(vs4, fs4, GL_FALSE))
758 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
762 bool Test(const std::string& vs, const std::string& fs, glw::GLint expectedLinkStatus)
764 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
765 const glw::GLuint p = gl.createProgram();
766 const std::string version = glu::getGLSLVersionDeclaration(m_glslVersion);
771 const std::string& body;
773 } shaderDefinition[] = { { "VS", vs, GL_VERTEX_SHADER }, { "FS", fs, GL_FRAGMENT_SHADER } };
775 for (unsigned int index = 0; index < 2; ++index)
777 std::string shaderSource = version + "\n" + shaderDefinition[index].body;
778 const char* shaderSourcePtr = shaderSource.c_str();
780 glw::GLuint sh = gl.createShader(shaderDefinition[index].type);
781 gl.attachShader(p, sh);
783 gl.shaderSource(sh, 1, &shaderSourcePtr, NULL);
784 gl.compileShader(sh);
787 gl.getShaderiv(sh, GL_COMPILE_STATUS, &status);
788 if (status == GL_FALSE)
791 gl.getShaderiv(sh, GL_INFO_LOG_LENGTH, &length);
794 std::vector<glw::GLchar> log(length);
795 gl.getShaderInfoLog(sh, length, NULL, &log[0]);
796 m_context.getTestContext().getLog() << tcu::TestLog::Message << shaderDefinition[index].name
797 << " compilation should succed. Info Log:\n"
798 << &log[0] << tcu::TestLog::EndMessage;
809 gl.getProgramiv(p, GL_LINK_STATUS, &status);
810 if (status != expectedLinkStatus)
812 if (status == GL_TRUE)
814 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Link operation should fail.\n"
815 << tcu::TestLog::EndMessage;
819 glw::GLchar log[1024];
820 gl.getProgramInfoLog(p, sizeof(log), NULL, log);
821 m_context.getTestContext().getLog()
822 << tcu::TestLog::Message << "Link operation should succed. Info Log:\n"
823 << log << tcu::TestLog::EndMessage;
833 glu::GLSLVersion m_glslVersion;
836 UniformBlockTests::UniformBlockTests(Context& context, glu::GLSLVersion glslVersion)
837 : TestCaseGroup(context, "uniform_block", "Uniform Block tests"), m_glslVersion(glslVersion)
841 UniformBlockTests::~UniformBlockTests(void)
845 void UniformBlockTests::init(void)
847 static const glu::DataType basicTypes[] = { glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT_VEC3,
848 glu::TYPE_FLOAT_VEC4, glu::TYPE_INT, glu::TYPE_INT_VEC2,
849 glu::TYPE_INT_VEC3, glu::TYPE_INT_VEC4, glu::TYPE_UINT,
850 glu::TYPE_UINT_VEC2, glu::TYPE_UINT_VEC3, glu::TYPE_UINT_VEC4,
851 glu::TYPE_BOOL, glu::TYPE_BOOL_VEC2, glu::TYPE_BOOL_VEC3,
852 glu::TYPE_BOOL_VEC4, glu::TYPE_FLOAT_MAT2, glu::TYPE_FLOAT_MAT3,
853 glu::TYPE_FLOAT_MAT4, glu::TYPE_FLOAT_MAT2X3, glu::TYPE_FLOAT_MAT2X4,
854 glu::TYPE_FLOAT_MAT3X2, glu::TYPE_FLOAT_MAT3X4, glu::TYPE_FLOAT_MAT4X2,
855 glu::TYPE_FLOAT_MAT4X3 };
861 } precisionFlags[] = { { "lowp", PRECISION_LOW }, { "mediump", PRECISION_MEDIUM }, { "highp", PRECISION_HIGH } };
867 } layoutFlags[] = { { "shared", LAYOUT_SHARED }, { "packed", LAYOUT_PACKED }, { "std140", LAYOUT_STD140 } };
873 } matrixFlags[] = { { "row_major", LAYOUT_ROW_MAJOR }, { "column_major", LAYOUT_COLUMN_MAJOR } };
878 UniformBlockCase::BufferMode mode;
879 } bufferModes[] = { { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
880 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE } };
882 // ubo.single_basic_type
884 tcu::TestCaseGroup* singleBasicTypeGroup =
885 new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
886 addChild(singleBasicTypeGroup);
888 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
890 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
891 singleBasicTypeGroup->addChild(layoutGroup);
893 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
895 glu::DataType type = basicTypes[basicTypeNdx];
896 const char* typeName = glu::getDataTypeName(type);
897 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
898 deUint32 flags = baseFlags | ((baseFlags & LAYOUT_PACKED) ?
899 (basicTypeNdx % 2 == 0 ? DECLARE_VERTEX : DECLARE_FRAGMENT) :
902 if (glu::isDataTypeBoolOrBVec(type))
903 layoutGroup->addChild(new BlockBasicTypeCase(m_context, typeName, "", m_glslVersion,
904 VarType(type, 0), flags, 0 /* no instance array */));
907 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
908 layoutGroup->addChild(new BlockBasicTypeCase(
909 m_context, (string(precisionFlags[precNdx].name) + "_" + typeName).c_str(), "",
910 m_glslVersion, VarType(type, precisionFlags[precNdx].flags), flags,
911 0 /* no instance array */));
914 if (glu::isDataTypeMatrix(type))
916 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
918 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
919 layoutGroup->addChild(new BlockBasicTypeCase(
921 (string(matrixFlags[matFlagNdx].name) + "_" + precisionFlags[precNdx].name + "_" +
924 "", m_glslVersion, VarType(type, precisionFlags[precNdx].flags),
925 flags | matrixFlags[matFlagNdx].flags, 0 /* no instance array */));
932 // ubo.single_basic_array
934 tcu::TestCaseGroup* singleBasicArrayGroup =
935 new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
936 addChild(singleBasicArrayGroup);
938 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
940 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
941 singleBasicArrayGroup->addChild(layoutGroup);
943 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
945 glu::DataType type = basicTypes[basicTypeNdx];
946 const char* typeName = glu::getDataTypeName(type);
947 const int arraySize = 3;
948 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
949 deUint32 flags = baseFlags | ((baseFlags & LAYOUT_PACKED) ?
950 (basicTypeNdx % 2 == 0 ? DECLARE_VERTEX : DECLARE_FRAGMENT) :
953 layoutGroup->addChild(new BlockBasicTypeCase(
954 m_context, typeName, "", m_glslVersion,
955 VarType(VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), arraySize), flags,
956 0 /* no instance array */));
958 if (glu::isDataTypeMatrix(type))
960 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
961 layoutGroup->addChild(new BlockBasicTypeCase(
962 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "",
963 m_glslVersion, VarType(VarType(type, PRECISION_HIGH), arraySize),
964 flags | matrixFlags[matFlagNdx].flags, 0 /* no instance array */));
972 tcu::TestCaseGroup* singleStructGroup =
973 new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in uniform block");
974 addChild(singleStructGroup);
976 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
978 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
980 for (int isArray = 0; isArray < 2; isArray++)
982 std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
983 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
984 deUint32 flags = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_VERTEX : DECLARE_BOTH);
986 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
987 continue; // Doesn't make sense to add this variant.
990 name += "_instance_array";
992 singleStructGroup->addChild(new BlockSingleStructCase(
993 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
999 // ubo.single_struct_array
1001 tcu::TestCaseGroup* singleStructArrayGroup =
1002 new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one uniform block");
1003 addChild(singleStructArrayGroup);
1005 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1007 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1009 for (int isArray = 0; isArray < 2; isArray++)
1011 std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
1012 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
1013 deUint32 flags = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_FRAGMENT : DECLARE_BOTH);
1015 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
1016 continue; // Doesn't make sense to add this variant.
1019 name += "_instance_array";
1021 singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(
1022 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1028 // ubo.single_nested_struct
1030 tcu::TestCaseGroup* singleNestedStructGroup =
1031 new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one uniform block");
1032 addChild(singleNestedStructGroup);
1034 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1036 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1038 for (int isArray = 0; isArray < 2; isArray++)
1040 std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
1041 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
1042 deUint32 flags = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_VERTEX : DECLARE_BOTH);
1044 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
1045 continue; // Doesn't make sense to add this variant.
1048 name += "_instance_array";
1050 singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(
1051 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1057 // ubo.single_nested_struct_array
1059 tcu::TestCaseGroup* singleNestedStructArrayGroup =
1060 new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one uniform block");
1061 addChild(singleNestedStructArrayGroup);
1063 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1065 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1067 for (int isArray = 0; isArray < 2; isArray++)
1069 std::string name = std::string(bufferModes[modeNdx].name) + "_" + layoutFlags[layoutFlagNdx].name;
1070 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
1071 deUint32 flags = baseFlags | ((baseFlags & LAYOUT_PACKED) ? DECLARE_FRAGMENT : DECLARE_BOTH);
1073 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
1074 continue; // Doesn't make sense to add this variant.
1077 name += "_instance_array";
1079 singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(
1080 m_context, name.c_str(), "", m_glslVersion, flags, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1086 // ubo.instance_array_basic_type
1088 tcu::TestCaseGroup* instanceArrayBasicTypeGroup =
1089 new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
1090 addChild(instanceArrayBasicTypeGroup);
1092 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1094 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
1095 instanceArrayBasicTypeGroup->addChild(layoutGroup);
1097 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
1099 glu::DataType type = basicTypes[basicTypeNdx];
1100 const char* typeName = glu::getDataTypeName(type);
1101 const int numInstances = 3;
1102 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
1103 deUint32 flags = baseFlags | ((baseFlags & LAYOUT_PACKED) ?
1104 (basicTypeNdx % 2 == 0 ? DECLARE_VERTEX : DECLARE_FRAGMENT) :
1107 layoutGroup->addChild(new BlockBasicTypeCase(
1108 m_context, typeName, "", m_glslVersion,
1109 VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), flags, numInstances));
1111 if (glu::isDataTypeMatrix(type))
1113 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
1114 layoutGroup->addChild(new BlockBasicTypeCase(
1115 m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(), "",
1116 m_glslVersion, VarType(type, PRECISION_HIGH), flags | matrixFlags[matFlagNdx].flags,
1123 // ubo.multi_basic_types
1125 tcu::TestCaseGroup* multiBasicTypesGroup =
1126 new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
1127 addChild(multiBasicTypesGroup);
1129 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1131 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1132 multiBasicTypesGroup->addChild(modeGroup);
1134 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1136 for (int isArray = 0; isArray < 2; isArray++)
1138 std::string baseName = layoutFlags[layoutFlagNdx].name;
1139 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
1142 baseName += "_instance_array";
1144 modeGroup->addChild(new BlockMultiBasicTypesCase(
1145 m_context, (baseName + "_mixed").c_str(), "", m_glslVersion, baseFlags | DECLARE_VERTEX,
1146 baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1148 if (!(baseFlags & LAYOUT_PACKED))
1149 modeGroup->addChild(new BlockMultiBasicTypesCase(
1150 m_context, (baseName + "_both").c_str(), "", m_glslVersion,
1151 baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
1152 baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1158 // ubo.multi_nested_struct
1160 tcu::TestCaseGroup* multiNestedStructGroup =
1161 new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
1162 addChild(multiNestedStructGroup);
1164 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
1166 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
1167 multiNestedStructGroup->addChild(modeGroup);
1169 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
1171 for (int isArray = 0; isArray < 2; isArray++)
1173 std::string baseName = layoutFlags[layoutFlagNdx].name;
1174 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
1177 baseName += "_instance_array";
1179 modeGroup->addChild(new BlockMultiNestedStructCase(
1180 m_context, (baseName + "_mixed").c_str(), "", m_glslVersion, baseFlags | DECLARE_VERTEX,
1181 baseFlags | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1183 if (!(baseFlags & LAYOUT_PACKED))
1184 modeGroup->addChild(new BlockMultiNestedStructCase(
1185 m_context, (baseName + "_both").c_str(), "", m_glslVersion,
1186 baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT,
1187 baseFlags | DECLARE_VERTEX | DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
1195 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS | FEATURE_FRAGMENT_BLOCKS | FEATURE_SHARED_BLOCKS;
1196 const deUint32 allLayouts = FEATURE_PACKED_LAYOUT | FEATURE_SHARED_LAYOUT | FEATURE_STD140_LAYOUT;
1197 const deUint32 allBasicTypes = FEATURE_VECTORS | FEATURE_MATRICES;
1198 const deUint32 unused = FEATURE_UNUSED_MEMBERS | FEATURE_UNUSED_UNIFORMS;
1199 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT;
1201 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
1202 addChild(randomGroup);
1205 createRandomCaseGroup(randomGroup, m_context, "scalar_types", "Scalar types only, per-block buffers",
1206 m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused,
1208 createRandomCaseGroup(randomGroup, m_context, "vector_types", "Scalar and vector types only, per-block buffers",
1209 m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
1210 allShaders | allLayouts | unused | FEATURE_VECTORS, 10, 25);
1211 createRandomCaseGroup(randomGroup, m_context, "basic_types", "All basic types, per-block buffers",
1212 m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
1213 allShaders | allLayouts | unused | allBasicTypes | matFlags, 10, 50);
1214 createRandomCaseGroup(randomGroup, m_context, "basic_arrays", "Arrays, per-block buffers", m_glslVersion,
1215 UniformBlockCase::BUFFERMODE_PER_BLOCK,
1216 allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_ARRAYS, 10, 50);
1218 createRandomCaseGroup(
1219 randomGroup, m_context, "basic_instance_arrays", "Basic instance arrays, per-block buffers", m_glslVersion,
1220 UniformBlockCase::BUFFERMODE_PER_BLOCK,
1221 allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_INSTANCE_ARRAYS, 10, 75);
1222 createRandomCaseGroup(randomGroup, m_context, "nested_structs", "Nested structs, per-block buffers",
1223 m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
1224 allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS, 10, 100);
1225 createRandomCaseGroup(
1226 randomGroup, m_context, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", m_glslVersion,
1227 UniformBlockCase::BUFFERMODE_PER_BLOCK,
1228 allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS | FEATURE_ARRAYS, 10, 150);
1229 createRandomCaseGroup(
1230 randomGroup, m_context, "nested_structs_instance_arrays",
1231 "Nested structs, instance arrays, per-block buffers", m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK,
1232 allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS | FEATURE_INSTANCE_ARRAYS, 10,
1234 createRandomCaseGroup(randomGroup, m_context, "nested_structs_arrays_instance_arrays",
1235 "Nested structs, instance arrays, per-block buffers", m_glslVersion,
1236 UniformBlockCase::BUFFERMODE_PER_BLOCK,
1237 allShaders | allLayouts | unused | allBasicTypes | matFlags | FEATURE_STRUCTS |
1238 FEATURE_ARRAYS | FEATURE_INSTANCE_ARRAYS,
1241 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers",
1242 m_glslVersion, UniformBlockCase::BUFFERMODE_PER_BLOCK, ~0u, 20, 200);
1243 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer",
1244 m_glslVersion, UniformBlockCase::BUFFERMODE_SINGLE, ~0u, 20, 250);
1248 if (glu::isGLSLVersionSupported(m_context.getRenderContext().getType(), glu::GLSL_VERSION_300_ES))
1250 tcu::TestCaseGroup* commonGroup = new tcu::TestCaseGroup(m_testCtx, "common", "Common Uniform Block cases");
1251 addChild(commonGroup);
1252 commonGroup->addChild(new UniformBlockPrecisionMatching(m_context, m_glslVersion));
1253 commonGroup->addChild(new UniformBlockNameMatching(m_context, m_glslVersion));
1255 else if (glu::isGLSLVersionSupported(m_context.getRenderContext().getType(), glu::GLSL_VERSION_150))
1257 tcu::TestCaseGroup* commonGroup = new tcu::TestCaseGroup(m_testCtx, "common", "Common Uniform Block cases");
1258 addChild(commonGroup);
1259 commonGroup->addChild(new UniformBlockNameMatching(m_context, m_glslVersion));