13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 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 Shader built-in variable tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fShaderBuiltinVarTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderRenderCase.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderExecUtil.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestCase.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrRenderer.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrFragmentOperations.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getInteger (const glw::Functions& gl, deUint32 pname)
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int value = -1;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(pname, &value);
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), ("glGetIntegerv(" + glu::getGettableStateStr((int)pname).toString() + ")").c_str());
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return value;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<deUint32 Pname>
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getInteger (const glw::Functions& gl)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getInteger(gl, Pname);
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getVectorsFromComps (const glw::Functions& gl, deUint32 pname)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int value = -1;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(pname, &value);
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), ("glGetIntegerv(" + glu::getGettableStateStr((int)pname).toString() + ")").c_str());
76edf4349eec0b57919082c021448ae6c10c3e61a2Kalle Raita	// Accept truncated division. According to the spec, the number of vectors is number of components divided by four, plain and simple.
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return value/4;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<deUint32 Pname>
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getVectorsFromComps (const glw::Functions& gl)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getVectorsFromComps(gl, Pname);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderBuiltinConstantCase : public TestCase
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef int (*GetConstantValueFunc) (const glw::Functions& gl);
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderBuiltinConstantCase	(Context& context, const char* name, const char* desc, const char* varName, GetConstantValueFunc getValue, glu::ShaderType shaderType);
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~ShaderBuiltinConstantCase	(void);
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string			m_varName;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GetConstantValueFunc	m_getValue;
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderType		m_shaderType;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderBuiltinConstantCase::ShaderBuiltinConstantCase (Context& context, const char* name, const char* desc, const char* varName, GetConstantValueFunc getValue, glu::ShaderType shaderType)
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase		(context, name, desc)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_varName		(varName)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_getValue	(getValue)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType	(shaderType)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderBuiltinConstantCase::~ShaderBuiltinConstantCase (void)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic gls::ShaderExecUtil::ShaderExecutor* createGetConstantExecutor (const glu::RenderContext& renderCtx, glu::ShaderType shaderType, const std::string& varName)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace gls::ShaderExecUtil;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderSpec	shaderSpec;
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderSpec.version	= glu::GLSL_VERSION_300_ES;
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderSpec.source	= string("result = ") + varName + ";\n";
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderSpec.outputs.push_back(Symbol("result", glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP)));
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return createExecutor(renderCtx, shaderType, shaderSpec);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderBuiltinConstantCase::IterateResult ShaderBuiltinConstantCase::iterate (void)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using namespace gls::ShaderExecUtil;
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const de::UniquePtr<ShaderExecutor>	shaderExecutor	(createGetConstantExecutor(m_context.getRenderContext(), m_shaderType, m_varName));
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							reference		= m_getValue(m_context.getRenderContext().getFunctions());
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int									result			= -1;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void* const							outputs			= &result;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!shaderExecutor->isOk())
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderExecutor->log(m_testCtx.getLog());
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_FAIL("Compile failed");
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderExecutor->useProgram();
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderExecutor->execute(1, DE_NULL, &outputs);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Integer(m_varName, m_varName, "", QP_KEY_TAG_NONE, result);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (result != reference)
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "ERROR: Expected " << m_varName << " = " << reference << TestLog::EndMessage
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   << TestLog::Message << "Test shader:" << TestLog::EndMessage;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderExecutor->log(m_testCtx.getLog());
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid builtin constant value");
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DepthRangeParams
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DepthRangeParams (void)
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: zNear	(0.0f)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, zFar	(1.0f)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DepthRangeParams (float zNear_, float zFar_)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: zNear	(zNear_)
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, zFar	(zFar_)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	zNear;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	zFar;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DepthRangeEvaluator : public gls::ShaderEvaluator
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DepthRangeEvaluator (const DepthRangeParams& params)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_params(params)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void evaluate (gls::ShaderEvalContext& c)
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float zNear	= deFloatClamp(m_params.zNear, 0.0f, 1.0f);
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float zFar	= deFloatClamp(m_params.zFar, 0.0f, 1.0f);
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float diff	= zFar - zNear;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		c.color.xyz() = tcu::Vec3(zNear, zFar, diff*0.5f + 0.5f);
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DepthRangeParams& m_params;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderDepthRangeTest : public gls::ShaderRenderCase
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderDepthRangeTest (Context& context, const char* name, const char* desc, bool isVertexCase)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc, isVertexCase, m_evaluator)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_evaluator		(m_depthRange)
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_iterNdx			(0)
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void init (void)
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const char* defaultVertSrc =
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_position;\n"
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position;\n"
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const char* defaultFragSrc =
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in mediump vec4 v_color;\n"
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 o_color;\n\n"
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = v_color;\n"
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Construct shader.
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::ostringstream src;
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "#version 300 es\n";
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_isVertexCase)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src << "in highp vec4 a_position;\n"
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "out mediump vec4 v_color;\n";
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src << "layout(location = 0) out mediump vec4 o_color;\n";
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "void main (void)\n{\n";
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "\t" << (m_isVertexCase ? "v_color" : "o_color") << " = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff*0.5 + 0.5, 1.0);\n";
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_isVertexCase)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src << "\tgl_Position = a_position;\n";
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "}\n";
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertShaderSource		= m_isVertexCase ? src.str()		: defaultVertSrc;
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fragShaderSource		= m_isVertexCase ? defaultFragSrc	: src.str();
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::ShaderRenderCase::init();
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult iterate (void)
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_renderCtx.getFunctions();
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const DepthRangeParams cases[] =
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DepthRangeParams(0.0f,  1.0f),
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DepthRangeParams(1.5f, -1.0f),
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DepthRangeParams(0.7f,  0.3f)
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_depthRange = cases[m_iterNdx];
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "glDepthRangef(" << m_depthRange.zNear << ", " << m_depthRange.zFar << ")" << tcu::TestLog::EndMessage;
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.depthRangef(m_depthRange.zNear, m_depthRange.zFar);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthRangef()");
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::ShaderRenderCase::iterate();
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_iterNdx += 1;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_iterNdx == DE_LENGTH_OF_ARRAY(cases) || m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return CONTINUE;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DepthRangeParams		m_depthRange;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DepthRangeEvaluator		m_evaluator;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_iterNdx;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FragCoordXYZCase : public TestCase
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FragCoordXYZCase (Context& context)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TestCase(context, "fragcoord_xyz", "gl_FragCoord.xyz Test")
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult iterate (void)
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&				log			= m_testCtx.getLog();
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				width		= m_context.getRenderTarget().getWidth();
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				height		= m_context.getRenderTarget().getHeight();
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA			threshold	= tcu::RGBA(1,1,1,1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3			scale		(1.f / float(width), 1.f / float(height), 1.0f);
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			testImg		(width, height);
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			refImg		(width, height);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_position;\n"
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position;\n"
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n",
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform highp vec3 u_scale;\n"
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 o_color;\n"
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = vec4(gl_FragCoord.xyz*u_scale, 1.0);\n"
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"));
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << program;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Compile failed");
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw with GL.
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float positions[] =
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				-1.0f,  1.0f, -1.0f, 1.0f,
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				-1.0f, -1.0f,  0.0f, 1.0f,
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 1.0f,  1.0f,  0.0f, 1.0f,
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 1.0f, -1.0f,  1.0f, 1.0f
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				scaleLoc	= gl.getUniformLocation(program.getProgram(), "u_scale");
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_position", 4, 4, 0, &positions[0]);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(program.getProgram());
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform3fv(scaleLoc, 1, scale.getPtr());
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), 0, 0, testImg.getAccess());
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw reference
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < refImg.getHeight(); y++)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < refImg.getWidth(); x++)
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float			xf			= (float(x)+.5f) / float(refImg.getWidth());
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float			yf			= (float(refImg.getHeight()-y-1)+.5f) / float(refImg.getHeight());
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float			z			= (xf + yf) / 2.0f;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::Vec3		fragCoord	(float(x)+.5f, float(y)+.5f, z);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::Vec3		scaledFC	= fragCoord*scale;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::Vec4		color		(scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				refImg.setPixel(x, y, tcu::RGBA(color));
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compare
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image comparison failed");
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float projectedTriInterpolate (const tcu::Vec3& s, const tcu::Vec3& w, float nx, float ny)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FragCoordWCase : public TestCase
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FragCoordWCase (Context& context)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TestCase(context, "fragcoord_w", "gl_FragCoord.w Test")
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult iterate (void)
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&				log			= m_testCtx.getLog();
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				width		= m_context.getRenderTarget().getWidth();
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				height		= m_context.getRenderTarget().getHeight();
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA			threshold	= tcu::RGBA(1,1,1,1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			testImg		(width, height);
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			refImg		(width, height);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float				w[4]		= { 1.7f, 2.0f, 1.2f, 1.0f };
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_position;\n"
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position;\n"
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n",
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 o_color;\n"
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = vec4(0.0, 1.0/gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"));
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << program;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Compile failed");
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw with GL.
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float positions[] =
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				-w[0],  w[0], 0.0f, w[0],
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				-w[1], -w[1], 0.0f, w[1],
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 w[2],  w[2], 0.0f, w[2],
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 w[3], -w[3], 0.0f, w[3]
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_position", 4, 4, 0, &positions[0]);
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(program.getProgram());
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), 0, 0, testImg.getAccess());
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw reference
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < refImg.getHeight(); y++)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < refImg.getWidth(); x++)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float			xf			= (float(x)+.5f) / float(refImg.getWidth());
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float			yf			= (float(refImg.getHeight()-y-1)+.5f) / float(refImg.getHeight());
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float			oow			= ((xf + yf) < 1.0f)
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												? projectedTriInterpolate(tcu::Vec3(w[0], w[1], w[2]), tcu::Vec3(w[0], w[1], w[2]), xf, yf)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												: projectedTriInterpolate(tcu::Vec3(w[3], w[2], w[1]), tcu::Vec3(w[3], w[2], w[1]), 1.0f-xf, 1.0f-yf);
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::Vec4		color		(0.0f, oow - 1.0f, 0.0f, 1.0f);
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				refImg.setPixel(x, y, tcu::RGBA(color));
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compare
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image comparison failed");
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PointCoordCase : public TestCase
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PointCoordCase (Context& context)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TestCase(context, "pointcoord", "gl_PointCoord Test")
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult iterate (void)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&				log			= m_testCtx.getLog();
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				width		= de::min(256, m_context.getRenderTarget().getWidth());
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				height		= de::min(256, m_context.getRenderTarget().getHeight());
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float				threshold	= 0.02f;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numPoints	= 8;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<tcu::Vec3>		coords		(numPoints);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float					pointSizeRange[2]	= { 0.0f, 0.0f };
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(0x145fa);
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			testImg		(width, height);
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			refImg		(width, height);
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, &pointSizeRange[0]);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE)");
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pointSizeRange[0] <= 0.0f || pointSizeRange[1] <= 0.0f || pointSizeRange[1] < pointSizeRange[0])
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Invalid GL_ALIASED_POINT_SIZE_RANGE");
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute coordinates.
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<tcu::Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				coord->x() = rnd.getFloat(-0.9f, 0.9f);
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				coord->y() = rnd.getFloat(-0.9f, 0.9f);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				coord->z() = rnd.getFloat(pointSizeRange[0], pointSizeRange[1]);
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec3 a_positionSize;\n"
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = vec4(a_positionSize.xy, 0.0, 1.0);\n"
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_PointSize = a_positionSize.z;\n"
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n",
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 o_color;\n"
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"));
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << program;
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Compile failed");
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw with GL.
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_positionSize", 3, (int)coords.size(), 0, (const float*)&coords[0]);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				viewportX	= rnd.getInt(0, m_context.getRenderTarget().getWidth()-width);
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				viewportY	= rnd.getInt(0, m_context.getRenderTarget().getHeight()-height);
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewportX, viewportY, width, height);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.clear(GL_COLOR_BUFFER_BIT);
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(program.getProgram());
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  glu::pr::Points((int)coords.size()));
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw reference
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(refImg.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<tcu::Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	x0		= deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) - pointIter->z()*0.5f);
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	y0		= deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) - pointIter->z()*0.5f);
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	x1		= deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) + pointIter->z()*0.5f);
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	y1		= deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) + pointIter->z()*0.5f);
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	w		= x1-x0;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	h		= y1-y0;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int yo = 0; yo < h; yo++)
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int xo = 0; xo < w; xo++)
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
569cff15864116080b023e12c0b4e73d02874b0a5a6Jarkko Pöyry					const float			xf		= (float(xo)+0.5f) / float(w);
570cff15864116080b023e12c0b4e73d02874b0a5a6Jarkko Pöyry					const float			yf		= (float(h-yo-1)+0.5f) / float(h);
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::Vec4		color	(xf, yf, 0.0f, 1.0f);
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int			dx		= x0+xo;
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int			dy		= y0+yo;
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (de::inBounds(dx, 0, refImg.getWidth()) && de::inBounds(dy, 0, refImg.getHeight()))
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						refImg.setPixel(dx, dy, tcu::RGBA(color));
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compare
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image comparison failed");
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FrontFacingCase : public TestCase
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FrontFacingCase (Context& context)
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TestCase(context, "frontfacing", "gl_FrontFacing Test")
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult iterate (void)
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Test case renders two adjecent quads, where left is has front-facing
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// triagles and right back-facing. Color is selected based on gl_FrontFacing
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// value.
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&				log			= m_testCtx.getLog();
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(0x89f2c);
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				width		= de::min(64, m_context.getRenderTarget().getWidth());
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				height		= de::min(64, m_context.getRenderTarget().getHeight());
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				viewportX	= rnd.getInt(0, m_context.getRenderTarget().getWidth()-width);
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				viewportY	= rnd.getInt(0, m_context.getRenderTarget().getHeight()-height);
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA			threshold	= tcu::RGBA(1,1,1,1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			testImg		(width, height);
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			refImg		(width, height);
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_position;\n"
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position;\n"
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n",
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 o_color;\n"
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	if (gl_FrontFacing)\n"
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	else\n"
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"));
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << program;
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program.isOk())
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Compile failed");
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw with GL.
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float positions[] =
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				-1.0f,  1.0f, 0.0f, 1.0f,
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				-1.0f, -1.0f, 0.0f, 1.0f,
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 1.0f,  1.0f, 0.0f, 1.0f,
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 1.0f, -1.0f, 0.0f, 1.0f
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint16 indicesCCW[]	= { 0, 1, 2, 2, 1, 3 };
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint16 indicesCW[]	= { 2, 1, 0, 3, 1, 2 };
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_position", 4, 4, 0, &positions[0]);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.useProgram(program.getProgram());
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewportX, viewportY, width/2, height);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCCW), &indicesCCW[0]));
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewportX + width/2, viewportY, width-width/2, height);
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCW), &indicesCW[0]));
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw reference
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < refImg.getHeight(); y++)
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < refImg.getWidth()/2; x++)
673c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski				refImg.setPixel(x, y, tcu::RGBA::green());
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = refImg.getWidth()/2; x < refImg.getWidth(); x++)
676c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski				refImg.setPixel(x, y, tcu::RGBA::blue());
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compare
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image comparison failed");
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// VertexIDCase
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VertexIDCase : public TestCase
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						VertexIDCase			(Context& context);
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~VertexIDCase			(void);
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init					(void);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit					(void);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate					(void);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAX_VERTICES = 8*3	//!< 8 triangles, totals 24 vertices
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderReference			(const tcu::PixelBufferAccess& dst, const int numVertices, const deUint16* const indices, const tcu::Vec4* const positions, const tcu::Vec4* const colors);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_program;
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			m_positionBuffer;
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			m_elementBuffer;
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<tcu::Vec4>	m_positions;
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<tcu::Vec4>	m_colors;
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_viewportW;
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_viewportH;
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_iterNdx;
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexIDCase::VertexIDCase (Context& context)
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, "vertex_id",	"gl_VertexID Test")
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program			(DE_NULL)
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_positionBuffer	(0)
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_elementBuffer	(0)
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportW		(0)
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportH		(0)
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_iterNdx			(0)
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexIDCase::~VertexIDCase (void)
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VertexIDCase::deinit();
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexIDCase::init (void)
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				width		= m_context.getRenderTarget().getWidth();
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				height		= m_context.getRenderTarget().getHeight();
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				quadWidth	= 32;
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				quadHeight	= 32;
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (width < quadWidth)
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target");
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				maxQuadsX	= width/quadWidth;
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numVertices	= MAX_VERTICES;
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numQuads	= numVertices/6 + (numVertices%6 != 0 ? 1 : 0);
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				viewportW	= de::min(numQuads, maxQuadsX)*quadWidth;
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				viewportH	= (numQuads/maxQuadsX + (numQuads%maxQuadsX != 0 ? 1 : 0))*quadHeight;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewportH > height)
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target");
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(viewportW <= width && viewportH <= height);
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec4 a_position;\n"
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out mediump vec4 v_color;\n"
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp vec4 u_colors[24];\n"
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_position;\n"
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color = u_colors[gl_VertexID];\n"
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n",
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in mediump vec4 v_color;\n"
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 o_color;\n"
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	o_color = v_color;\n"
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"));
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_program;
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_program->isOk())
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_program;
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = DE_NULL;
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Compile failed");
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &m_positionBuffer);
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &m_elementBuffer);
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set colors (in dynamic memory to save static data space).
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors.resize(numVertices);
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 1] = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 2] = tcu::Vec4(0.0f, 0.5f, 1.0f, 1.0f);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 3] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 4] = tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f);
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 5] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 6] = tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f);
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 7] = tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f);
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 8] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[ 9] = tcu::Vec4(0.5f, 1.0f, 0.0f, 1.0f);
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[10] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[11] = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[12] = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[13] = tcu::Vec4(1.0f, 0.0f, 0.5f, 1.0f);
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[14] = tcu::Vec4(0.0f, 0.5f, 0.5f, 1.0f);
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[15] = tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f);
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[16] = tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[17] = tcu::Vec4(1.0f, 0.5f, 0.0f, 1.0f);
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[18] = tcu::Vec4(0.0f, 1.0f, 0.5f, 1.0f);
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[19] = tcu::Vec4(1.0f, 0.5f, 1.0f, 1.0f);
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[20] = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[21] = tcu::Vec4(1.0f, 0.5f, 0.5f, 1.0f);
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[22] = tcu::Vec4(0.0f, 0.0f, 0.5f, 1.0f);
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors[23] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute positions.
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_positions.resize(numVertices);
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numVertices%3 == 0);
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx += 3)
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	h			= 2.0f * float(quadHeight)/float(viewportH);
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	w			= 2.0f * float(quadWidth)/float(viewportW);
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	triNdx		= vtxNdx/3;
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	quadNdx		= triNdx/2;
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	quadY		= quadNdx/maxQuadsX;
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	quadX		= quadNdx%maxQuadsX;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8349790daae5762b391f1a26bee4fb88a008fe4b583Jarkko Pöyry		const float	x0			= -1.0f + float(quadX)*w;
8359790daae5762b391f1a26bee4fb88a008fe4b583Jarkko Pöyry		const float	y0			= -1.0f + float(quadY)*h;
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (triNdx%2 == 0)
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_positions[vtxNdx+0] = tcu::Vec4(x0,   y0,   0.0f, 1.0f);
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_positions[vtxNdx+1] = tcu::Vec4(x0+w, y0+h, 0.0f, 1.0f);
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_positions[vtxNdx+2] = tcu::Vec4(x0,   y0+h, 0.0f, 1.0f);
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_positions[vtxNdx+0] = tcu::Vec4(x0+w, y0+h, 0.0f, 1.0f);
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_positions[vtxNdx+1] = tcu::Vec4(x0,   y0,   0.0f, 1.0f);
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_positions[vtxNdx+2] = tcu::Vec4(x0+w, y0,   0.0f, 1.0f);
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportW	= viewportW;
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportH	= viewportH;
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_iterNdx	= 0;
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexIDCase::deinit (void)
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_positionBuffer)
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_positionBuffer);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_positionBuffer = 0;
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_elementBuffer)
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_elementBuffer);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_elementBuffer = 0;
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_positions.clear();
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colors.clear();
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VertexIDReferenceShader : public rr::VertexShader, public rr::FragmentShader
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VARYINGLOC_COLOR = 0
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VertexIDReferenceShader ()
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: rr::VertexShader	(2, 1)		// color and pos in => color out
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, rr::FragmentShader(1, 1)		// color in => color out
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_inputs[0].type		= rr::GENERICVECTYPE_FLOAT;
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_inputs[1].type		= rr::GENERICVECTYPE_FLOAT;
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_outputs[0].type		= rr::GENERICVECTYPE_FLOAT;
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_outputs[0].flatshade	= false;
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::FragmentShader::m_inputs[0].type		= rr::GENERICVECTYPE_FLOAT;
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::FragmentShader::m_inputs[0].flatshade	= false;
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::FragmentShader::m_outputs[0].type		= rr::GENERICVECTYPE_FLOAT;
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int positionAttrLoc = 0;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int colorAttrLoc = 1;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::VertexPacket& packet = *packets[packetNdx];
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Transform to position
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.position = rr::readVertexAttribFloat(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx);
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Pass color to FS
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.outputs[VARYINGLOC_COLOR] = rr::readVertexAttribFloat(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx);
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::FragmentPacket& packet = packets[packetNdx];
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readVarying<float>(packet, context, VARYINGLOC_COLOR, fragNdx));
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexIDCase::renderReference (const tcu::PixelBufferAccess& dst, const int numVertices, const deUint16* const indices, const tcu::Vec4* const positions, const tcu::Vec4* const colors)
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::Renderer				referenceRenderer;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::RenderState			referenceState		((rr::ViewportState)(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(dst)));
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::RenderTarget			referenceTarget		(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(dst));
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VertexIDReferenceShader	referenceShader;
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	      rr::VertexAttrib			attribs[2];
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[0].type				= rr::VERTEXATTRIBTYPE_FLOAT;
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[0].size				= 4;
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[0].stride			= 0;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[0].instanceDivisor	= 0;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[0].pointer			= positions;
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[1].type				= rr::VERTEXATTRIBTYPE_FLOAT;
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[1].size				= 4;
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[1].stride			= 0;
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[1].instanceDivisor	= 0;
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[1].pointer			= colors;
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceRenderer.draw(
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::DrawCommand(
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			referenceState,
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			referenceTarget,
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::Program(&referenceShader, &referenceShader),
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			2,
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribs,
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, numVertices, rr::DrawIndices(indices))));
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexIDCase::IterateResult VertexIDCase::iterate (void)
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				width		= m_context.getRenderTarget().getWidth();
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				height		= m_context.getRenderTarget().getHeight();
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				viewportW	= m_viewportW;
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				viewportH	= m_viewportH;
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float				threshold	= 0.02f;
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd			(0xcf23ab1 ^ deInt32Hash(m_iterNdx));
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			refImg		(viewportW, viewportH);
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			testImg		(viewportW, viewportH);
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				viewportX	= rnd.getInt(0, width-viewportW);
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				viewportY	= rnd.getInt(0, height-viewportH);
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				posLoc		= gl.getAttribLocation(m_program->getProgram(), "a_position");
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				colorsLoc	= gl.getUniformLocation(m_program->getProgram(), "u_colors[0]");
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4			clearColor	(0.0f, 0.0f, 0.0f, 1.0f);
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup common state.
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport					(viewportX, viewportY, viewportW, viewportH);
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram				(m_program->getProgram());
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer				(GL_ARRAY_BUFFER, m_positionBuffer);
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableVertexAttribArray	(posLoc);
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribPointer		(posLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.uniform4fv				(colorsLoc, (int)m_colors.size(), (const float*)&m_colors[0]);
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear render target to black.
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor	(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear		(GL_COLOR_BUFFER_BIT);
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(refImg.getAccess(), clearColor);
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_iterNdx == 0)
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ScopedLogSection	logSection	(m_testCtx.getLog(), "Iter0", "glDrawArrays()");
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint16>		indices		(m_positions.size());
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, (int)(m_positions.size()*sizeof(tcu::Vec4)), &m_positions[0], GL_DYNAMIC_DRAW);
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawArrays(GL_TRIANGLES, 0, (int)m_positions.size());
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Reference indices
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)indices.size(); ndx++)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			indices[ndx] = (deUint16)ndx;
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderReference(refImg.getAccess(), (int)m_positions.size(), &indices[0], &m_positions[0], &m_colors[0]);
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_iterNdx == 1)
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ScopedLogSection	logSection	(m_testCtx.getLog(), "Iter1", "glDrawElements(), indices in client-side array");
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint16>		indices		(m_positions.size());
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<tcu::Vec4>		mappedPos	(m_positions.size());
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute initial indices and suffle
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)indices.size(); ndx++)
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			indices[ndx] = (deUint16)ndx;
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rnd.shuffle(indices.begin(), indices.end());
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Use indices to re-map positions.
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)indices.size(); ndx++)
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mappedPos[indices[ndx]] = m_positions[ndx];
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, (int)(m_positions.size()*sizeof(tcu::Vec4)), &mappedPos[0], GL_DYNAMIC_DRAW);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawElements(GL_TRIANGLES, (int)indices.size(), GL_UNSIGNED_SHORT, &indices[0]);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderReference(refImg.getAccess(), (int)indices.size(), &indices[0], &mappedPos[0], &m_colors[0]);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_iterNdx == 2)
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ScopedLogSection	logSection	(m_testCtx.getLog(), "Iter2", "glDrawElements(), indices in buffer");
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint16>		indices		(m_positions.size());
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<tcu::Vec4>		mappedPos	(m_positions.size());
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute initial indices and suffle
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)indices.size(); ndx++)
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			indices[ndx] = (deUint16)ndx;
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rnd.shuffle(indices.begin(), indices.end());
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Use indices to re-map positions.
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)indices.size(); ndx++)
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mappedPos[indices[ndx]] = m_positions[ndx];
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuffer);
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (int)(indices.size()*sizeof(deUint16)), &indices[0], GL_DYNAMIC_DRAW);
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, (int)(m_positions.size()*sizeof(tcu::Vec4)), &mappedPos[0], GL_DYNAMIC_DRAW);
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawElements(GL_TRIANGLES, (int)indices.size(), GL_UNSIGNED_SHORT, DE_NULL);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(refImg.getAccess(), clearColor);
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderReference(refImg.getAccess(), (int)indices.size(), &indices[0], &mappedPos[0], &m_colors[0]);
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT))
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_iterNdx += 1;
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (m_iterNdx < 3) ? CONTINUE : STOP;
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderBuiltinVarTests::ShaderBuiltinVarTests (Context& context)
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "builtin_variable", "Built-in Variable Tests")
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderBuiltinVarTests::~ShaderBuiltinVarTests (void)
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderBuiltinVarTests::init (void)
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Builtin constants.
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*											caseName;
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*											varName;
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShaderBuiltinConstantCase::GetConstantValueFunc		getValue;
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} builtinConstants[] =
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// GLES 2.
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_vertex_attribs",					"gl_MaxVertexAttribs",				getInteger<GL_MAX_VERTEX_ATTRIBS>						},
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_vertex_uniform_vectors",			"gl_MaxVertexUniformVectors",		getInteger<GL_MAX_VERTEX_UNIFORM_VECTORS>				},
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_fragment_uniform_vectors",		"gl_MaxFragmentUniformVectors",		getInteger<GL_MAX_FRAGMENT_UNIFORM_VECTORS>				},
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_texture_image_units",			"gl_MaxTextureImageUnits",			getInteger<GL_MAX_TEXTURE_IMAGE_UNITS>					},
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_vertex_texture_image_units",		"gl_MaxVertexTextureImageUnits",	getInteger<GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS>			},
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_combined_texture_image_units",	"gl_MaxCombinedTextureImageUnits",	getInteger<GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS>			},
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_draw_buffers",					"gl_MaxDrawBuffers",				getInteger<GL_MAX_DRAW_BUFFERS>							},
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// GLES 3.
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_vertex_output_vectors",			"gl_MaxVertexOutputVectors",		getVectorsFromComps<GL_MAX_VERTEX_OUTPUT_COMPONENTS>	},
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_fragment_input_vectors",			"gl_MaxFragmentInputVectors",		getVectorsFromComps<GL_MAX_FRAGMENT_INPUT_COMPONENTS>	},
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "min_program_texel_offset",			"gl_MinProgramTexelOffset",			getInteger<GL_MIN_PROGRAM_TEXEL_OFFSET>					},
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "max_program_texel_offset",			"gl_MaxProgramTexelOffset",			getInteger<GL_MAX_PROGRAM_TEXEL_OFFSET>					}
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtinConstants); ndx++)
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const										caseName	= builtinConstants[ndx].caseName;
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const										varName		= builtinConstants[ndx].varName;
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ShaderBuiltinConstantCase::GetConstantValueFunc	getValue	= builtinConstants[ndx].getValue;
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new ShaderBuiltinConstantCase(m_context, (string(caseName) + "_vertex").c_str(),	varName, varName, getValue, glu::SHADERTYPE_VERTEX));
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(new ShaderBuiltinConstantCase(m_context, (string(caseName) + "_fragment").c_str(),	varName, varName, getValue, glu::SHADERTYPE_FRAGMENT));
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new ShaderDepthRangeTest(m_context, "depth_range_vertex",		"gl_DepthRange", true));
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new ShaderDepthRangeTest(m_context, "depth_range_fragment",	"gl_DepthRange", false));
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Vertex shader builtin variables.
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new VertexIDCase		(m_context));
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2013-03-20 pyry] gl_InstanceID -- tested in instancing tests quite thoroughly.
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fragment shader builtin variables.
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new FragCoordXYZCase	(m_context));
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new FragCoordWCase		(m_context));
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new PointCoordCase		(m_context));
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new FrontFacingCase	(m_context));
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1140