1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Uniform block tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fUniformBlockTests.hpp"
25 #include "glsUniformBlockCase.hpp"
26 #include "glsRandomUniformBlockCase.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "deRandom.hpp"
29 #include "deStringUtil.hpp"
30
31 using std::string;
32 using std::vector;
33
34 namespace deqp
35 {
36 namespace gles31
37 {
38 namespace Functional
39 {
40 namespace
41 {
42
43 using gls::UniformBlockCase;
44 using gls::RandomUniformBlockCase;
45 using namespace gls::ub;
46
createRandomCaseGroup(tcu::TestCaseGroup * parentGroup,Context & context,const char * groupName,const char * description,UniformBlockCase::BufferMode bufferMode,deUint32 features,int numCases,deUint32 baseSeed)47 void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, Context& context, const char* groupName, const char* description, UniformBlockCase::BufferMode bufferMode, deUint32 features, int numCases, deUint32 baseSeed)
48 {
49 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(context.getTestContext(), groupName, description);
50 parentGroup->addChild(group);
51
52 baseSeed += (deUint32)context.getTestContext().getCommandLine().getBaseSeed();
53
54 for (int ndx = 0; ndx < numCases; ndx++)
55 group->addChild(new RandomUniformBlockCase(context.getTestContext(), context.getRenderContext(), glu::GLSL_VERSION_310_ES,
56 de::toString(ndx).c_str(), "", bufferMode, features, (deUint32)ndx+baseSeed));
57 }
58
59 class BlockBasicTypeCase : public UniformBlockCase
60 {
61 public:
BlockBasicTypeCase(Context & context,const char * name,const char * description,const VarType & type,deUint32 layoutFlags,int numInstances)62 BlockBasicTypeCase (Context& context, const char* name, const char* description, const VarType& type, deUint32 layoutFlags, int numInstances)
63 : UniformBlockCase(context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_310_ES, BUFFERMODE_PER_BLOCK)
64 {
65 UniformBlock& block = m_interface.allocBlock("Block");
66 block.addUniform(Uniform("var", type, 0));
67 block.setFlags(layoutFlags);
68
69 if (numInstances > 0)
70 {
71 block.setArraySize(numInstances);
72 block.setInstanceName("block");
73 }
74 }
75 };
76
createBlockBasicTypeCases(tcu::TestCaseGroup * group,Context & context,const char * name,const VarType & type,deUint32 layoutFlags,int numInstances=0)77 static void createBlockBasicTypeCases (tcu::TestCaseGroup* group, Context& context, const char* name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
78 {
79 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_vertex").c_str(), "", type, layoutFlags|DECLARE_VERTEX, numInstances));
80 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_fragment").c_str(), "", type, layoutFlags|DECLARE_FRAGMENT, numInstances));
81
82 if (!(layoutFlags & LAYOUT_PACKED))
83 group->addChild(new BlockBasicTypeCase(context, (string(name) + "_both").c_str(), "", type, layoutFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, numInstances));
84 }
85
86 class Block2LevelStructArrayCase : public UniformBlockCase
87 {
88 public:
Block2LevelStructArrayCase(Context & context,const char * name,const char * description,deUint32 layoutFlags,BufferMode bufferMode,int numInstances)89 Block2LevelStructArrayCase (Context& context, const char* name, const char* description, deUint32 layoutFlags, BufferMode bufferMode, int numInstances)
90 : UniformBlockCase (context.getTestContext(), context.getRenderContext(), name, description, glu::GLSL_VERSION_310_ES, bufferMode)
91 , m_layoutFlags (layoutFlags)
92 , m_numInstances (numInstances)
93 {
94 }
95
init(void)96 void init (void)
97 {
98 StructType& typeS = m_interface.allocStruct("S");
99 typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), UNUSED_BOTH);
100 typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 4));
101 typeS.addMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW));
102
103 UniformBlock& block = m_interface.allocBlock("Block");
104 block.addUniform(Uniform("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM)));
105 block.addUniform(Uniform("s", VarType(VarType(VarType(&typeS), 3), 2)));
106 block.addUniform(Uniform("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM)));
107 block.setFlags(m_layoutFlags);
108
109 if (m_numInstances > 0)
110 {
111 block.setInstanceName("block");
112 block.setArraySize(m_numInstances);
113 }
114 }
115
116 private:
117 deUint32 m_layoutFlags;
118 int m_numInstances;
119 };
120
121 } // anonymous
122
UniformBlockTests(Context & context)123 UniformBlockTests::UniformBlockTests (Context& context)
124 : TestCaseGroup(context, "ubo", "Uniform Block tests")
125 {
126 }
127
~UniformBlockTests(void)128 UniformBlockTests::~UniformBlockTests (void)
129 {
130 }
131
init(void)132 void UniformBlockTests::init (void)
133 {
134 static const glu::DataType basicTypes[] =
135 {
136 glu::TYPE_FLOAT,
137 glu::TYPE_FLOAT_VEC2,
138 glu::TYPE_FLOAT_VEC3,
139 glu::TYPE_FLOAT_VEC4,
140 glu::TYPE_INT,
141 glu::TYPE_INT_VEC2,
142 glu::TYPE_INT_VEC3,
143 glu::TYPE_INT_VEC4,
144 glu::TYPE_UINT,
145 glu::TYPE_UINT_VEC2,
146 glu::TYPE_UINT_VEC3,
147 glu::TYPE_UINT_VEC4,
148 glu::TYPE_BOOL,
149 glu::TYPE_BOOL_VEC2,
150 glu::TYPE_BOOL_VEC3,
151 glu::TYPE_BOOL_VEC4,
152 glu::TYPE_FLOAT_MAT2,
153 glu::TYPE_FLOAT_MAT3,
154 glu::TYPE_FLOAT_MAT4,
155 glu::TYPE_FLOAT_MAT2X3,
156 glu::TYPE_FLOAT_MAT2X4,
157 glu::TYPE_FLOAT_MAT3X2,
158 glu::TYPE_FLOAT_MAT3X4,
159 glu::TYPE_FLOAT_MAT4X2,
160 glu::TYPE_FLOAT_MAT4X3
161 };
162
163 static const struct
164 {
165 const char* name;
166 deUint32 flags;
167 } layoutFlags[] =
168 {
169 { "shared", LAYOUT_SHARED },
170 { "packed", LAYOUT_PACKED },
171 { "std140", LAYOUT_STD140 }
172 };
173
174 static const struct
175 {
176 const char* name;
177 deUint32 flags;
178 } matrixFlags[] =
179 {
180 { "row_major", LAYOUT_ROW_MAJOR },
181 { "column_major", LAYOUT_COLUMN_MAJOR }
182 };
183
184 static const struct
185 {
186 const char* name;
187 UniformBlockCase::BufferMode mode;
188 } bufferModes[] =
189 {
190 { "per_block_buffer", UniformBlockCase::BUFFERMODE_PER_BLOCK },
191 { "single_buffer", UniformBlockCase::BUFFERMODE_SINGLE }
192 };
193
194 // ubo.2_level_array
195 {
196 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level basic array variable in single buffer");
197 addChild(nestedArrayGroup);
198
199 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
200 {
201 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
202 nestedArrayGroup->addChild(layoutGroup);
203
204 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
205 {
206 const glu::DataType type = basicTypes[basicTypeNdx];
207 const char* typeName = glu::getDataTypeName(type);
208 const int childSize = 4;
209 const int parentSize = 3;
210 const VarType childType (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize);
211 const VarType parentType (childType, parentSize);
212
213 createBlockBasicTypeCases(layoutGroup, m_context, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
214
215 if (glu::isDataTypeMatrix(type))
216 {
217 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
218 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
219 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
220 }
221 }
222 }
223 }
224
225 // ubo.3_level_array
226 {
227 tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
228 addChild(nestedArrayGroup);
229
230 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
231 {
232 tcu::TestCaseGroup* layoutGroup = new tcu::TestCaseGroup(m_testCtx, layoutFlags[layoutFlagNdx].name, "");
233 nestedArrayGroup->addChild(layoutGroup);
234
235 for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
236 {
237 const glu::DataType type = basicTypes[basicTypeNdx];
238 const char* typeName = glu::getDataTypeName(type);
239 const int childSize0 = 2;
240 const int childSize1 = 4;
241 const int parentSize = 3;
242 const VarType childType0 (VarType(type, glu::isDataTypeBoolOrBVec(type) ? 0 : PRECISION_HIGH), childSize0);
243 const VarType childType1 (childType0, childSize1);
244 const VarType parentType (childType1, parentSize);
245
246 createBlockBasicTypeCases(layoutGroup, m_context, typeName, parentType, layoutFlags[layoutFlagNdx].flags);
247
248 if (glu::isDataTypeMatrix(type))
249 {
250 for (int matFlagNdx = 0; matFlagNdx < DE_LENGTH_OF_ARRAY(matrixFlags); matFlagNdx++)
251 createBlockBasicTypeCases(layoutGroup, m_context, (string(matrixFlags[matFlagNdx].name) + "_" + typeName).c_str(),
252 parentType, layoutFlags[layoutFlagNdx].flags|matrixFlags[matFlagNdx].flags);
253 }
254 }
255 }
256 }
257
258 // ubo.2_level_struct_array
259 {
260 tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one uniform block");
261 addChild(structArrayArrayGroup);
262
263 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(bufferModes); modeNdx++)
264 {
265 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[modeNdx].name, "");
266 structArrayArrayGroup->addChild(modeGroup);
267
268 for (int layoutFlagNdx = 0; layoutFlagNdx < DE_LENGTH_OF_ARRAY(layoutFlags); layoutFlagNdx++)
269 {
270 for (int isArray = 0; isArray < 2; isArray++)
271 {
272 std::string baseName = layoutFlags[layoutFlagNdx].name;
273 deUint32 baseFlags = layoutFlags[layoutFlagNdx].flags;
274
275 if (bufferModes[modeNdx].mode == UniformBlockCase::BUFFERMODE_SINGLE && isArray == 0)
276 continue; // Doesn't make sense to add this variant.
277
278 if (isArray)
279 baseName += "_instance_array";
280
281 modeGroup->addChild(new Block2LevelStructArrayCase(m_context, (baseName + "_vertex").c_str(), "", baseFlags|DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
282 modeGroup->addChild(new Block2LevelStructArrayCase(m_context, (baseName + "_fragment").c_str(), "", baseFlags|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
283
284 if (!(baseFlags & LAYOUT_PACKED))
285 modeGroup->addChild(new Block2LevelStructArrayCase(m_context, (baseName + "_both").c_str(), "", baseFlags|DECLARE_VERTEX|DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
286 }
287 }
288 }
289 }
290
291 // ubo.random
292 {
293 const deUint32 allShaders = FEATURE_VERTEX_BLOCKS|FEATURE_FRAGMENT_BLOCKS|FEATURE_SHARED_BLOCKS;
294 const deUint32 allLayouts = FEATURE_PACKED_LAYOUT|FEATURE_SHARED_LAYOUT|FEATURE_STD140_LAYOUT;
295 const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES;
296 const deUint32 unused = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
297 const deUint32 matFlags = FEATURE_MATRIX_LAYOUT;
298 const deUint32 basicTypeArrays = allShaders|allLayouts|unused|allBasicTypes|matFlags|FEATURE_ARRAYS|FEATURE_ARRAYS_OF_ARRAYS;
299 const deUint32 allFeatures = ~0u;
300
301 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
302 addChild(randomGroup);
303
304 createRandomCaseGroup(randomGroup, m_context, "basic_type_arrays", "Arrays, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, basicTypeArrays, 25, 1150);
305 createRandomCaseGroup(randomGroup, m_context, "all_per_block_buffers", "All random features, per-block buffers", UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures, 50, 11200);
306 createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer", UniformBlockCase::BUFFERMODE_SINGLE, allFeatures, 50, 11250);
307 }
308 }
309
310 } // Functional
311 } // gles31
312 } // deqp
313