Home | History | Annotate | Download | only in functional
      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
    313