Fix PIPELINE_STAGE_TOP_OF_PIPE_BIT usage in api tests
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fUniformBlockTests.cpp
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
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:
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
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:
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
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
123 UniformBlockTests::UniformBlockTests (Context& context)
124         : TestCaseGroup(context, "ubo", "Uniform Block tests")
125 {
126 }
127
128 UniformBlockTests::~UniformBlockTests (void)
129 {
130 }
131
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