• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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