13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Explicit uniform location tests
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fUniformLocationTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderLibrary.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarType.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarTypeUtil.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrContextUtil.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::UniquePtr;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::VarType;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct UniformInfo
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ShaderStage
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERSTAGE_NONE	= 0,
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERSTAGE_VERTEX	= (1<<0),
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERSTAGE_FRAGMENT= (1<<1),
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERSTAGE_BOTH	= (SHADERSTAGE_VERTEX | SHADERSTAGE_FRAGMENT),
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarType			type;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderStage		declareLocation; // support declarations with/without layout qualifiers, needed for linkage testing
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderStage		layoutLocation;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderStage		checkLocation;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				location; // -1 for unset
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformInfo (VarType type_, ShaderStage declareLocation_, ShaderStage layoutLocation_, ShaderStage checkLocation_, int location_ = -1)
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: type				(type_)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, declareLocation	(declareLocation_)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, layoutLocation	(layoutLocation_)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, checkLocation		(checkLocation_)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, location			(location_)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformLocationCase : public tcu::TestCase
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformLocationCase		(tcu::TestContext&			context,
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 glu::RenderContext&		renderContext,
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 const char*				name,
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 const char*				desc,
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 const vector<UniformInfo>&	uniformInfo);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 					~UniformLocationCase	(void) {}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult		iterate					(void);
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				run						(const vector<UniformInfo>& uniformList);
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static glu::ProgramSources	genShaderSources		(const vector<UniformInfo>& uniformList);
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						verifyLocations			(const glu::ShaderProgram& program, const vector<UniformInfo>& uniformList);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						render					(const glu::ShaderProgram& program, const vector<UniformInfo>& uniformList);
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static bool					verifyResult			(const tcu::ConstPixelBufferAccess& access);
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static float				getExpectedValue		(glu::DataType type, int id, const char* name);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::MovePtr<glu::Texture2D>	createTexture			(glu::DataType samplerType, float redChannelValue, int binding);
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&			m_renderCtx;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<UniformInfo>	m_uniformInfo;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RENDER_SIZE = 16
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring getUniformName (int ndx, const glu::VarType& type, const glu::TypeComponentVector& path)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buff;
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buff << "uni" << ndx << glu::TypeAccessFormat(type, path);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buff.str();
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring getFirstComponentName (const glu::VarType& type)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buff;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeVector(type.getBasicType()))
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buff << glu::TypeAccessFormat(type, glu::SubTypeAccess(type).component(0).getPath());
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeMatrix(type.getBasicType()))
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buff << glu::TypeAccessFormat(type, glu::SubTypeAccess(type).column(0).component(0).getPath());
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buff.str();
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformLocationCase::UniformLocationCase (tcu::TestContext&				context,
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  glu::RenderContext&			renderContext,
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  const char*					name,
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  const char*					desc,
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  const vector<UniformInfo>&	uniformInfo)
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderContext)
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformInfo		(uniformInfo)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// [from, to]
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::vector<int> shuffledRange (int from, int to, int seed)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	count	= to - from;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<int> retval	(count);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random	rng		(seed);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(count > 0);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < count; ndx++)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		retval[ndx] = ndx + from;
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rng.shuffle(retval.begin(), retval.end());
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retval;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::DataType getDataTypeSamplerSampleType (glu::DataType type)
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace glu;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type >= TYPE_SAMPLER_1D && type <= TYPE_SAMPLER_3D)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return TYPE_FLOAT_VEC4;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type >= TYPE_INT_SAMPLER_1D && type <= TYPE_INT_SAMPLER_3D)
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return TYPE_INT_VEC4;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type >= TYPE_UINT_SAMPLER_1D && type <= TYPE_UINT_SAMPLER_3D)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return TYPE_UINT_VEC4;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type >= TYPE_SAMPLER_1D_SHADOW && type <=	TYPE_SAMPLER_2D_ARRAY_SHADOW)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return TYPE_FLOAT;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!"Unknown sampler type");
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return TYPE_INVALID;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// A (hopefully) unique value for a uniform. For multi-component types creates only one value. Values are in the range [0,1] for floats, [-128, 127] for ints, [0,255] for uints and 0/1 for booleans. Samplers are treated according to the types they return.
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat UniformLocationCase::getExpectedValue (glu::DataType type, int id, const char* name)
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	hash			= deStringHash(name) + deInt32Hash(id);
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType	adjustedType	= type;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeSampler(type))
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		adjustedType = getDataTypeSamplerSampleType(type);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeIntOrIVec(adjustedType))
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return float(hash%128);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeUintOrUVec(adjustedType))
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return float(hash%255);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeFloatOrVec(adjustedType))
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (hash%255)/255.0f;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(adjustedType))
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return float(hash%2);
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!"Unkown primitive type");
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::TYPE_INVALID;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformLocationCase::IterateResult UniformLocationCase::iterate (void)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return run(m_uniformInfo);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformLocationCase::IterateResult UniformLocationCase::run (const vector<UniformInfo>& uniformList)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using gls::TextureTestUtil::RandomViewport;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ProgramSources	sources		= genShaderSources(uniformList);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram	program		(m_renderCtx, sources);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					baseSeed	= m_testCtx.getCommandLine().getBaseSeed();
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl			= m_renderCtx.getFunctions();
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport		viewport	(m_renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName()) + baseSeed);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				rendered	(RENDER_SIZE, RENDER_SIZE);
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!verifyLocations(program, uniformList))
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	render(program, uniformList);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewport.x, viewport.y, rendered.getAccess());
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!verifyResult(rendered.getAccess()))
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader produced incorrect result");
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ProgramSources UniformLocationCase::genShaderSources (const vector<UniformInfo>& uniformList)
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	vertDecl, vertMain, fragDecl, fragMain;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertDecl << "#version 310 es\n"
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "precision highp float;\n"
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "precision highp int;\n"
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "float verify(float val, float ref) { return float(abs(val-ref) < 0.05); }\n\n"
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "in highp vec4 a_position;\n"
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "out highp vec4 v_color;\n";
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragDecl << "#version 310 es\n\n"
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "precision highp float;\n"
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "precision highp int;\n"
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "float verify(float val, float ref) { return float(abs(val-ref) < 0.05); }\n\n"
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "in highp vec4 v_color;\n"
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "layout(location = 0) out mediump vec4 o_color;\n\n";
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertMain << "void main()\n{\n"
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "	gl_Position = a_position;\n"
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "	v_color = vec4(1.0);\n";
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragMain << "void main()\n{\n"
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 << "	o_color = v_color;\n";
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::set<const glu::StructType*> declaredStructs;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Declare uniforms
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int uniformNdx = 0; uniformNdx < int(uniformList.size()); uniformNdx++)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const UniformInfo&	uniformInfo = uniformList[uniformNdx];
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			declareInVert	= (uniformInfo.declareLocation & UniformInfo::SHADERSTAGE_VERTEX)   != 0;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			declareInFrag	= (uniformInfo.declareLocation & UniformInfo::SHADERSTAGE_FRAGMENT) != 0;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			layoutInVert    = (uniformInfo.layoutLocation  & UniformInfo::SHADERSTAGE_VERTEX)   != 0;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			layoutInFrag    = (uniformInfo.layoutLocation  & UniformInfo::SHADERSTAGE_FRAGMENT) != 0;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			checkInVert		= (uniformInfo.checkLocation   & UniformInfo::SHADERSTAGE_VERTEX)   != 0;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			checkInFrag		= (uniformInfo.checkLocation   & UniformInfo::SHADERSTAGE_FRAGMENT) != 0;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string		layout			= uniformInfo.location >= 0 ? "layout(location = " + de::toString(uniformInfo.location) + ") " : "";
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string		uniName			= "uni" + de::toString(uniformNdx);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					location		= uniformInfo.location;
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					subTypeIndex	= 0;
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT((declareInVert && layoutInVert) || !layoutInVert); // Cannot have layout without declaration
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT((declareInFrag && layoutInFrag) || !layoutInFrag);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(location<0 || (layoutInVert || layoutInFrag)); // Cannot have location without layout
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// struct definitions
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniformInfo.type.isStructType())
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::StructType* const structType = uniformInfo.type.getStructPtr();
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!declaredStructs.count(structType))
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (declareInVert)
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					vertDecl << glu::declare(structType, 0) << ";\n";
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (declareInFrag)
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					fragDecl << glu::declare(structType, 0) << ";\n";
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				declaredStructs.insert(structType);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (declareInVert)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vertDecl << "uniform " << (layoutInVert ? layout : "") << glu::declare(uniformInfo.type, uniName) << ";\n";
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (declareInFrag)
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fragDecl << "uniform " << (layoutInFrag ? layout : "") << glu::declare(uniformInfo.type, uniName) << ";\n";
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Anything that needs to be done for each enclosed primitive type
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (glu::BasicTypeIterator subTypeIter = glu::BasicTypeIterator::begin(&uniformInfo.type); subTypeIter != glu::BasicTypeIterator::end(&uniformInfo.type); subTypeIter++, subTypeIndex++)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::VarType	subType		= glu::getVarType(uniformInfo.type, subTypeIter.getPath());
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::DataType	scalarType	= glu::getDataTypeScalarType(subType.getBasicType());
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const	typeName	= glu::getDataTypeName(scalarType);
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string		expectValue	= de::floatToString(getExpectedValue(scalarType, location >= 0 ? location+subTypeIndex : -1, typeName), 3);
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isDataTypeSampler(scalarType))
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (checkInVert)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					vertMain << "	v_color.rgb *= verify(float( texture(" << uniName
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << glu::TypeAccessFormat(uniformInfo.type, subTypeIter.getPath())
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << ", vec2(0.5)).r), " << expectValue << ");\n";
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (checkInFrag)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					fragMain << "	o_color.rgb *= verify(float( texture(" << uniName
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << glu::TypeAccessFormat(uniformInfo.type, subTypeIter.getPath())
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << ", vec2(0.5)).r), " << expectValue << ");\n";
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (checkInVert)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					vertMain << "	v_color.rgb *= verify(float(" << uniName
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << glu::TypeAccessFormat(uniformInfo.type, subTypeIter.getPath())
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << getFirstComponentName(subType) << "), " << expectValue << ");\n";
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (checkInFrag)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					fragMain << "	o_color.rgb *= verify(float(" << uniName
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << glu::TypeAccessFormat(uniformInfo.type, subTypeIter.getPath())
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 << getFirstComponentName(subType) << "), " << expectValue << ");\n";
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertMain << "}\n";
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragMain << "}\n";
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::makeVtxFragSources(vertDecl.str() + vertMain.str(), fragDecl.str() + fragMain.str());
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformLocationCase::verifyLocations (const glu::ShaderProgram& program, const vector<UniformInfo>& uniformList)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_renderCtx.getFunctions();
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				vertexOk	= program.getShaderInfo(glu::SHADERTYPE_VERTEX).compileOk;
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				fragmentOk	= program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				linkOk		= program.getProgramInfo().linkOk;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			programID	= program.getProgram();
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log			= m_testCtx.getLog();
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::set<int>			usedLocations;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << program;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!vertexOk || !fragmentOk || !linkOk)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "ERROR: shader failed to compile/link" << TestLog::EndMessage;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader failed to compile/link");
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int uniformNdx = 0; uniformNdx < int(uniformList.size()); uniformNdx++)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const UniformInfo&	uniformInfo		= uniformList[uniformNdx];
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					subTypeIndex	= 0;
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (glu::BasicTypeIterator subTypeIter = glu::BasicTypeIterator::begin(&uniformInfo.type); subTypeIter != glu::BasicTypeIterator::end(&uniformInfo.type); subTypeIter++, subTypeIndex++)
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string		name		= getUniformName(uniformNdx, uniformInfo.type, subTypeIter.getPath());
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int			gotLoc		= gl.getUniformLocation(programID, name.c_str());
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int			expectLoc	= uniformInfo.location >= 0 ? uniformInfo.location+subTypeIndex : -1;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (expectLoc >= 0)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (uniformInfo.checkLocation == 0 && gotLoc == -1)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (gotLoc != expectLoc)
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "ERROR: found uniform " << name << " in location " << gotLoc << " when it should have been in " << expectLoc << TestLog::EndMessage;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect uniform location");
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (usedLocations.find(expectLoc) != usedLocations.end())
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "ERROR: expected uniform " << name << " in location " << gotLoc << " but it has already been used" << TestLog::EndMessage;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Overlapping uniform location");
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				usedLocations.insert(expectLoc);
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (gotLoc >= 0)
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (usedLocations.count(gotLoc))
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "ERROR: found uniform " << name << " in location " << gotLoc << " which has already been used" << TestLog::EndMessage;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Overlapping uniform location");
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				usedLocations.insert(gotLoc);
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Check that shader output is white (or very close to it)
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformLocationCase::verifyResult (const tcu::ConstPixelBufferAccess& access)
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::Vec4;
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 threshold (0.1f, 0.1f, 0.1f, 0.1f);
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 reference (1.0f, 1.0f, 1.0f, 1.0f);
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < access.getHeight(); y++)
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < access.getWidth(); x++)
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4 diff = abs(access.getPixel(x, y) - reference);
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!boolAll(lessThanEqual(diff, threshold)))
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// get a 4 channel 8 bits each texture format that is usable by the given sampler type
4573c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 getTextureFormat (glu::DataType samplerType)
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace glu;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (samplerType)
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_SAMPLER_1D:
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_SAMPLER_2D:
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_SAMPLER_CUBE:
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_SAMPLER_2D_ARRAY:
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_SAMPLER_3D:
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GL_RGBA8;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_INT_SAMPLER_1D:
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_INT_SAMPLER_2D:
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_INT_SAMPLER_CUBE:
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_INT_SAMPLER_2D_ARRAY:
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_INT_SAMPLER_3D:
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GL_RGBA8I;
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_UINT_SAMPLER_1D:
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_UINT_SAMPLER_2D:
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_UINT_SAMPLER_CUBE:
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_UINT_SAMPLER_2D_ARRAY:
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_UINT_SAMPLER_3D:
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GL_RGBA8UI;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!"Unsupported (sampler) type");
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// create a texture suitable for sampling by the given sampler type and bind it
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryde::MovePtr<glu::Texture2D> UniformLocationCase::createTexture (glu::DataType samplerType, float redChannelValue, int binding)
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace glu;
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		 = m_renderCtx.getFunctions();
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			format	 = getTextureFormat(samplerType);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::MovePtr<Texture2D>	tex;
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tex = de::MovePtr<Texture2D>(new Texture2D(m_renderCtx, format, 16, 16));
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tex->getRefTexture().allocLevel(0);
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (format == GL_RGBA8I || format == GL_RGBA8UI)
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(tex->getRefTexture().getLevel(0), tcu::IVec4(int(redChannelValue), 0, 0, 0));
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(tex->getRefTexture().getLevel(0), tcu::Vec4(redChannelValue, 0.0f, 0.0f, 1.0f));
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0 + binding);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tex->upload();
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(GL_TEXTURE_2D, tex->getGLTexture());
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformLocationCase: texture upload");
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tex;
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformLocationCase::render (const glu::ShaderProgram& program, const vector<UniformInfo>& uniformList)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using glu::Texture2D;
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using de::MovePtr;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef vector<Texture2D*> TextureList;
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_renderCtx.getFunctions();
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			programID		= program.getProgram();
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32			posLoc			= gl.getAttribLocation(programID, "a_position");
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Vertex data.
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float position[] =
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.0f, -1.0f, 0.1f,	1.0f,
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.0f,  1.0f, 0.1f,	1.0f,
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.0f, -1.0f, 0.1f,	1.0f,
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.0f,  1.0f, 0.1f,	1.0f
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16			indices[]		= { 0, 1, 2, 2, 1, 3 };
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// some buffers to feed to the GPU, only the first element is relevant since the others are never verified
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float					floatBuf[16]	= {0.0f};
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32					intBuf[4]		= {0};
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				uintBuf[4]		= {0};
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureList				texList;
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(posLoc >= 0);
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(programID);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Set uniforms
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (unsigned int uniformNdx = 0; uniformNdx < uniformList.size(); uniformNdx++)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformInfo&	uniformInfo			= uniformList[uniformNdx];
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					expectedLocation	= uniformInfo.location;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (glu::BasicTypeIterator subTypeIter = glu::BasicTypeIterator::begin(&uniformInfo.type); subTypeIter != glu::BasicTypeIterator::end(&uniformInfo.type); subTypeIter++)
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::VarType	type			= glu::getVarType(uniformInfo.type, subTypeIter.getPath());
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name			= getUniformName(uniformNdx, uniformInfo.type, subTypeIter.getPath());
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			gotLoc			= gl.getUniformLocation(programID, name.c_str());
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::DataType	scalarType		= glu::getDataTypeScalarType(type.getBasicType());
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*	const	typeName		= glu::getDataTypeName(scalarType);
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float			expectedValue	= getExpectedValue(scalarType, expectedLocation, typeName);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (glu::isDataTypeSampler(scalarType))
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int binding = (int)texList.size();
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					texList.push_back(createTexture(scalarType, expectedValue, binding).release());
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform1i(gotLoc, binding);
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else if(gotLoc >= 0)
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					floatBuf[0] = expectedValue;
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					intBuf[0]   = int(expectedValue);
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uintBuf[0]  = deUint32(expectedValue);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.getLog() << tcu::TestLog::Message << "Set uniform " << name << " in location " << gotLoc << " to " << expectedValue << tcu::TestLog::EndMessage;
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					switch (type.getBasicType())
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT:			gl.uniform1fv(gotLoc, 1, floatBuf);					break;
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_VEC2:		gl.uniform2fv(gotLoc, 1, floatBuf);					break;
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_VEC3:		gl.uniform3fv(gotLoc, 1, floatBuf);					break;
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_VEC4:		gl.uniform4fv(gotLoc, 1, floatBuf);					break;
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_INT:				gl.uniform1iv(gotLoc, 1, intBuf);					break;
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_INT_VEC2:		gl.uniform2iv(gotLoc, 1, intBuf);					break;
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_INT_VEC3:		gl.uniform3iv(gotLoc, 1, intBuf);					break;
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_INT_VEC4:		gl.uniform4iv(gotLoc, 1, intBuf);					break;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_UINT:			gl.uniform1uiv(gotLoc, 1, uintBuf);					break;
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_UINT_VEC2:		gl.uniform2uiv(gotLoc, 1, uintBuf);					break;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_UINT_VEC3:		gl.uniform3uiv(gotLoc, 1, uintBuf);					break;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_UINT_VEC4:		gl.uniform4uiv(gotLoc, 1, uintBuf);					break;
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_BOOL:			gl.uniform1iv(gotLoc, 1, intBuf);					break;
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_BOOL_VEC2:		gl.uniform2iv(gotLoc, 1, intBuf);					break;
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_BOOL_VEC3:		gl.uniform3iv(gotLoc, 1, intBuf);					break;
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_BOOL_VEC4:		gl.uniform4iv(gotLoc, 1, intBuf);					break;
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT2:		gl.uniformMatrix2fv(gotLoc, 1, false, floatBuf);	break;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT2X3:	gl.uniformMatrix2x3fv(gotLoc, 1, false, floatBuf);	break;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT2X4:	gl.uniformMatrix2x4fv(gotLoc, 1, false, floatBuf);	break;
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT3X2:	gl.uniformMatrix3x2fv(gotLoc, 1, false, floatBuf);	break;
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT3:		gl.uniformMatrix3fv(gotLoc, 1, false, floatBuf);	break;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT3X4:	gl.uniformMatrix3x4fv(gotLoc, 1, false, floatBuf);	break;
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT4X2:	gl.uniformMatrix4x2fv(gotLoc, 1, false, floatBuf);	break;
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT4X3:	gl.uniformMatrix4x3fv(gotLoc, 1, false, floatBuf);	break;
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case glu::TYPE_FLOAT_MAT4:		gl.uniformMatrix4fv(gotLoc, 1, false, floatBuf);	break;
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						default:
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							DE_ASSERT(false);
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				expectedLocation += expectedLocation>=0;
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(posLoc);
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_SHORT, &indices[0]);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disableVertexAttribArray(posLoc);
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch(...)
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < int(texList.size()); i++)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete texList[i];
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < int(texList.size()); i++)
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete texList[i];
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MaxUniformLocationCase : public UniformLocationCase
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								MaxUniformLocationCase		(tcu::TestContext&			context,
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 glu::RenderContext&		renderContext,
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				name,
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				desc,
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const vector<UniformInfo>&	uniformInfo);
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 					~MaxUniformLocationCase		(void) {}
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult		iterate						(void);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMaxUniformLocationCase::MaxUniformLocationCase (tcu::TestContext&			context,
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												glu::RenderContext&			renderContext,
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												const char*					name,
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												const char*					desc,
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												const vector<UniformInfo>&	uniformInfo)
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformLocationCase(context, renderContext, name, desc, uniformInfo)
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!uniformInfo.empty());
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformLocationCase::IterateResult MaxUniformLocationCase::iterate (void)
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					maxLocation = 1024;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<UniformInfo>	uniformInfo = m_uniformInfo;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderCtx.getFunctions().getIntegerv(GL_MAX_UNIFORM_LOCATIONS, &maxLocation);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformInfo[0].location = maxLocation-1;
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return UniformLocationCase::run(uniformInfo);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Anonymous
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformLocationTests::UniformLocationTests (Context& context)
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "uniform_location", "Explicit uniform locations")
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformLocationTests::~UniformLocationTests (void)
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < int(structTypes.size()); i++)
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete structTypes[i];
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::VarType createVarType (glu::DataType type)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::VarType(type, glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_HIGHP);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformLocationTests::init (void)
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace glu;
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UniformInfo::ShaderStage checkStages[]	= { UniformInfo::SHADERSTAGE_VERTEX, UniformInfo::SHADERSTAGE_FRAGMENT };
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*						stageNames[]	= {"vertex", "fragment"};
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						maxLocations	= 1024;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						baseSeed		= m_context.getTestContext().getCommandLine().getBaseSeed();
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DataType					primitiveTypes[] =
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT,
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_VEC2,
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_VEC3,
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_VEC4,
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_INT,
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_INT_VEC2,
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_INT_VEC3,
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_INT_VEC4,
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_UINT,
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_UINT_VEC2,
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_UINT_VEC3,
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_UINT_VEC4,
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_BOOL,
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_BOOL_VEC2,
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_BOOL_VEC3,
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_BOOL_VEC4,
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT2,
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT2X3,
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT2X4,
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT3X2,
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT3,
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT3X4,
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT4X2,
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT4X3,
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT4,
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_SAMPLER_2D,
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_INT_SAMPLER_2D,
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_UINT_SAMPLER_2D,
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int maxPrimitiveTypeNdx = DE_LENGTH_OF_ARRAY(primitiveTypes) - 4;
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(primitiveTypes[maxPrimitiveTypeNdx] == TYPE_FLOAT_MAT4);
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Primitive type cases with trivial linkage
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, "basic", "Location specified with use, single shader stage");
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random					rng		(baseSeed + 0x1001);
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveNdx++)
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const DataType		type	= primitiveTypes[primitiveNdx];
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(checkStages); stageNdx++)
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= string(getDataTypeName(type)) + "_" + stageNames[stageNdx];
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<UniformInfo> config;
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				UniformInfo			uniform	(createVarType(type),
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 rng.getInt(0, maxLocations-1));
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(uniform);
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new UniformLocationCase (m_testCtx, m_context.getRenderContext(), name.c_str(), name.c_str(), config));
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Arrays
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, "array", "Array location specified with use, single shader stage");
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random					rng		(baseSeed + 0x2001);
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveNdx++)
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const DataType		type	= primitiveTypes[primitiveNdx];
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(checkStages); stageNdx++)
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name	= string(getDataTypeName(type)) + "_" + stageNames[stageNdx];
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<UniformInfo> config;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				UniformInfo			uniform	(VarType(createVarType(type), 8),
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												checkStages[stageNdx],
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												checkStages[stageNdx],
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												checkStages[stageNdx],
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												rng.getInt(0, maxLocations-1-8));
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(uniform);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new UniformLocationCase (m_testCtx, m_context.getRenderContext(), name.c_str(), name.c_str(), config));
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Nested Arrays
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, "nested_array", "Array location specified with use, single shader stage");
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random					rng		(baseSeed + 0x3001);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveNdx++)
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const DataType		type	= primitiveTypes[primitiveNdx];
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(checkStages); stageNdx++)
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= string(getDataTypeName(type)) + "_" + stageNames[stageNdx];
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// stay comfortably within minimum max uniform component count (896 in fragment) and sampler count with all types
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			arraySize	= (getDataTypeScalarSize(type) > 4 || isDataTypeSampler(type)) ? 3 : 7;
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<UniformInfo> config;
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				UniformInfo			uniform	(VarType(VarType(createVarType(type), arraySize), arraySize),
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 rng.getInt(0, maxLocations-1-arraySize*arraySize));
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(uniform);
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new UniformLocationCase (m_testCtx, m_context.getRenderContext(), name.c_str(), name.c_str(), config));
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Structs
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, "struct", "Struct location, random contents & declaration location");
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random					rng		(baseSeed + 0x4001);
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 0; caseNdx < 16; caseNdx++)
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			typedef UniformInfo::ShaderStage Stage;
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	name		= "case_" + de::toString(caseNdx);
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Stage		layoutLoc	= Stage(rng.getUint32()&0x3);
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Stage		declareLoc	= Stage((rng.getUint32()&0x3) | layoutLoc);
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Stage		verifyLoc	= Stage((rng.getUint32()&0x3) & declareLoc);
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		location	= layoutLoc ? rng.getInt(0, maxLocations-1-5) : -1;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			StructType*		structProto = new StructType("S");
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structTypes.push_back(structProto);
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structProto->addMember("a", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structProto->addMember("b", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structProto->addMember("c", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structProto->addMember("d", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structProto->addMember("e", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<UniformInfo> config;
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(UniformInfo(VarType(structProto),
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 declareLoc,
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLoc,
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 verifyLoc,
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 location));
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new UniformLocationCase (m_testCtx, m_context.getRenderContext(), name.c_str(), name.c_str(), config));
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Nested Structs
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, "nested_struct", "Struct location specified with use, single shader stage");
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random					rng		(baseSeed + 0x5001);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 0; caseNdx < 16; caseNdx++)
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			typedef UniformInfo::ShaderStage Stage;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	name		= "case_" + de::toString(caseNdx);
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		baseLoc		= rng.getInt(0, maxLocations-1-60);
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Structs need to be added in the order of their declaration
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Stage		layoutLocs[]=
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3),
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3),
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3),
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3),
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	tempDecl[] =
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(rng.getUint32()&0x3) | layoutLocs[0],
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(rng.getUint32()&0x3) | layoutLocs[1],
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(rng.getUint32()&0x3) | layoutLocs[2],
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(rng.getUint32()&0x3) | layoutLocs[3],
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Component structs need to be declared if anything using them is declared
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Stage		declareLocs[] =
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(tempDecl[0] | tempDecl[1] | tempDecl[2] | tempDecl[3]),
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(tempDecl[1] | tempDecl[2] | tempDecl[3]),
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(tempDecl[2] | tempDecl[3]),
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(tempDecl[3]),
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Stage		verifyLocs[] =
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3 & declareLocs[0]),
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3 & declareLocs[1]),
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3 & declareLocs[2]),
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Stage(rng.getUint32()&0x3 & declareLocs[3]),
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			StructType*		testTypes[]	=
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				new StructType("Type0"),
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				new StructType("Type1"),
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				new StructType("Type2"),
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				new StructType("Type3"),
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structTypes.push_back(testTypes[0]);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structTypes.push_back(testTypes[1]);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structTypes.push_back(testTypes[2]);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structTypes.push_back(testTypes[3]);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[0]->addMember("a", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[0]->addMember("b", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[0]->addMember("c", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[0]->addMember("d", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[0]->addMember("e", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[1]->addMember("a", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[1]->addMember("b", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[1]->addMember("c", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[1]->addMember("d", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[1]->addMember("e", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[2]->addMember("a", VarType(testTypes[0]));
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[2]->addMember("b", VarType(testTypes[1]));
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[2]->addMember("c", createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]));
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			testTypes[3]->addMember("a", VarType(testTypes[2]));
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<UniformInfo> config;
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(UniformInfo(VarType(testTypes[0]),
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 declareLocs[0],
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[0],
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 verifyLocs[0],
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[0] ? baseLoc : -1));
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(UniformInfo(VarType(testTypes[1]),
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 declareLocs[1],
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[1],
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 verifyLocs[1],
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[1] ? baseLoc+5 : -1));
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(UniformInfo(VarType(testTypes[2]),
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 declareLocs[2],
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[2],
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 verifyLocs[2],
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[2] ? baseLoc+16 : -1));
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(UniformInfo(VarType(testTypes[3]),
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 declareLocs[3],
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[3],
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 verifyLocs[3],
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 layoutLocs[3] ? baseLoc+27 : -1));
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new UniformLocationCase (m_testCtx, m_context.getRenderContext(), name.c_str(), name.c_str(), config));
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Min/Max location
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group		= new tcu::TestCaseGroup(m_testCtx, "min_max", "Maximum & minimum location");
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveNdx++)
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const DataType		type	= primitiveTypes[primitiveNdx];
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(checkStages); stageNdx++)
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= string(getDataTypeName(type)) + "_" + stageNames[stageNdx];
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<UniformInfo> config;
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(UniformInfo(createVarType(type),
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 checkStages[stageNdx],
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 0));
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new UniformLocationCase (m_testCtx, m_context.getRenderContext(), (name+"_min").c_str(), (name+"_min").c_str(), config));
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new MaxUniformLocationCase (m_testCtx, m_context.getRenderContext(), (name+"_max").c_str(), (name+"_max").c_str(), config));
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Link
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, "link", "Location specified independently from use");
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random					rng		(baseSeed + 0x82e1);
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 0; caseNdx < 10; caseNdx++)
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string		name		= "case_" + de::toString(caseNdx);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<UniformInfo> config;
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<int>			locations	= shuffledRange(0, maxLocations, 0x1234 + caseNdx*100);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int count = 0; count < 32; count++)
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				typedef UniformInfo::ShaderStage Stage;
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Stage			layoutLoc	= Stage(rng.getUint32()&0x3);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Stage			declareLoc	= Stage((rng.getUint32()&0x3) | layoutLoc);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Stage			verifyLoc	= Stage((rng.getUint32()&0x3) & declareLoc);
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformInfo	uniform		(createVarType(primitiveTypes[rng.getInt(0, maxPrimitiveTypeNdx)]),
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 declareLoc,
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 layoutLoc,
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 verifyLoc,
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 (layoutLoc!=0) ? locations.back() : -1);
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				config.push_back(uniform);
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				locations.pop_back();
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			group->addChild(new UniformLocationCase (m_testCtx, m_context.getRenderContext(), name.c_str(), name.c_str(), config));
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Negative
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::ShaderLibrary			shaderLibrary    (m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<TestNode*>     negativeCases    = shaderLibrary.loadShaderFile("shaders/uniform_location.test");
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	group			 = new tcu::TestCaseGroup(m_testCtx, "negative", "Negative tests");
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group);
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < int(negativeCases.size()); ndx++)
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			group->addChild(negativeCases[ndx]);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1063