/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Shader built-in variable tests.
 *//*--------------------------------------------------------------------*/

#include "es2fShaderBuiltinVarTests.hpp"
#include "glsShaderRenderCase.hpp"
#include "deRandom.hpp"
#include "deString.h"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuTestCase.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuImageCompare.hpp"
#include "gluPixelTransfer.hpp"
#include "gluDrawUtil.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

using std::string;
using std::vector;
using tcu::TestLog;

namespace deqp
{
namespace gles2
{
namespace Functional
{

const float builtinConstScale = 4.0f;

void evalBuiltinConstant (gls::ShaderEvalContext& c)
{
	bool isOk = 0 == (int)(deFloatFloor(c.coords.x() * builtinConstScale) + 0.05f);
	c.color = isOk ? tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f) : tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

class ShaderBuiltinConstantCase : public gls::ShaderRenderCase
{
public:
						ShaderBuiltinConstantCase				(Context& context, const char* name, const char* desc, const char* varName, deUint32 paramName, bool isVertexCase);
						~ShaderBuiltinConstantCase				(void);

	int					getRefValue								(void);
	void				init									(void);

private:
	const std::string	m_varName;
	const deUint32		m_paramName;
};

ShaderBuiltinConstantCase::ShaderBuiltinConstantCase (Context& context, const char* name, const char* desc, const char* varName, deUint32 paramName, bool isVertexCase)
	: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc, isVertexCase, evalBuiltinConstant)
	, m_varName			(varName)
	, m_paramName		(paramName)
{
}

ShaderBuiltinConstantCase::~ShaderBuiltinConstantCase (void)
{
}

int ShaderBuiltinConstantCase::getRefValue (void)
{
	if (m_varName == "gl_MaxDrawBuffers")
	{
		if (m_ctxInfo.isExtensionSupported("GL_EXT_draw_buffers"))
			return m_ctxInfo.getInt(GL_MAX_DRAW_BUFFERS);
		else
			return 1;
	}
	else
	{
		DE_ASSERT(m_paramName != GL_NONE);
		return m_ctxInfo.getInt(m_paramName);
	}
}

void ShaderBuiltinConstantCase::init (void)
{
	const int refValue = getRefValue();
	m_testCtx.getLog() << tcu::TestLog::Message << m_varName << " = " << refValue << tcu::TestLog::EndMessage;

	static const char* defaultVertSrc =
		"attribute highp vec4 a_position;\n"
		"attribute highp vec4 a_coords;\n"
		"varying mediump vec4 v_coords;\n\n"
		"void main (void)\n"
		"{\n"
		"	v_coords = a_coords;\n"
		"	gl_Position = a_position;\n"
		"}\n";
	static const char* defaultFragSrc =
		"varying mediump vec4 v_color;\n\n"
		"void main (void)\n"
		"{\n"
		"	gl_FragColor = v_color;\n"
		"}\n";

	// Construct shader.
	std::ostringstream src;
	if (m_isVertexCase)
	{
		src << "attribute highp vec4 a_position;\n"
			<< "attribute highp vec4 a_coords;\n"
			<< "varying mediump vec4 v_color;\n";
	}
	else
		src << "varying mediump vec4 v_coords;\n";

	src << "void main (void)\n{\n";

	src << "\tbool isOk = " << m_varName << " == (" << refValue << " + int(floor(" << (m_isVertexCase ? "a_coords" : "v_coords") << ".x * " << de::floatToString(builtinConstScale, 1) << ") + 0.05));\n";
	src << "\t" << (m_isVertexCase ? "v_color" : "gl_FragColor") << " = isOk ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);\n";

	if (m_isVertexCase)
		src << "\tgl_Position = a_position;\n";

	src << "}\n";

	m_vertShaderSource		= m_isVertexCase ? src.str()		: defaultVertSrc;
	m_fragShaderSource		= m_isVertexCase ? defaultFragSrc	: src.str();

	gls::ShaderRenderCase::init();
}

namespace
{

struct DepthRangeParams
{
	DepthRangeParams (void)
		: zNear	(0.0f)
		, zFar	(1.0f)
	{
	}

	DepthRangeParams (float zNear_, float zFar_)
		: zNear	(zNear_)
		, zFar	(zFar_)
	{
	}

	float	zNear;
	float	zFar;
};

class DepthRangeEvaluator : public gls::ShaderEvaluator
{
public:
	DepthRangeEvaluator (const DepthRangeParams& params)
		: m_params(params)
	{
	}

	void evaluate (gls::ShaderEvalContext& c)
	{
		float zNear	= deFloatClamp(m_params.zNear, 0.0f, 1.0f);
		float zFar	= deFloatClamp(m_params.zFar, 0.0f, 1.0f);
		float diff	= zFar - zNear;
		c.color.xyz() = tcu::Vec3(zNear, zFar, diff*0.5f + 0.5f);
	}

private:
	const DepthRangeParams& m_params;
};

} // anonymous

class ShaderDepthRangeTest : public gls::ShaderRenderCase
{
public:
	ShaderDepthRangeTest (Context& context, const char* name, const char* desc, bool isVertexCase)
		: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc, isVertexCase, m_evaluator)
		, m_evaluator		(m_depthRange)
		, m_iterNdx			(0)
	{
	}

	void init (void)
	{
		static const char* defaultVertSrc =
			"attribute highp vec4 a_position;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"}\n";
		static const char* defaultFragSrc =
			"varying mediump vec4 v_color;\n\n"
			"void main (void)\n"
			"{\n"
			"	gl_FragColor = v_color;\n"
			"}\n";

		// Construct shader.
		std::ostringstream src;
		if (m_isVertexCase)
			src << "attribute highp vec4 a_position;\n"
				<< "varying mediump vec4 v_color;\n";

		src << "void main (void)\n{\n";
		src << "\t" << (m_isVertexCase ? "v_color" : "gl_FragColor") << " = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff*0.5 + 0.5, 1.0);\n";

		if (m_isVertexCase)
			src << "\tgl_Position = a_position;\n";

		src << "}\n";

		m_vertShaderSource		= m_isVertexCase ? src.str()		: defaultVertSrc;
		m_fragShaderSource		= m_isVertexCase ? defaultFragSrc	: src.str();

		gls::ShaderRenderCase::init();
	}

	IterateResult iterate (void)
	{
		const glw::Functions& gl = m_renderCtx.getFunctions();

		const DepthRangeParams cases[] =
		{
			DepthRangeParams(0.0f,  1.0f),
			DepthRangeParams(1.5f, -1.0f),
			DepthRangeParams(0.7f,  0.3f)
		};

		m_depthRange = cases[m_iterNdx];
		m_testCtx.getLog() << tcu::TestLog::Message << "glDepthRangef(" << m_depthRange.zNear << ", " << m_depthRange.zFar << ")" << tcu::TestLog::EndMessage;
		gl.depthRangef(m_depthRange.zNear, m_depthRange.zFar);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthRangef()");

		gls::ShaderRenderCase::iterate();
		m_iterNdx += 1;

		if (m_iterNdx == DE_LENGTH_OF_ARRAY(cases) || m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
			return STOP;
		else
			return CONTINUE;
	}

private:
	DepthRangeParams		m_depthRange;
	DepthRangeEvaluator		m_evaluator;
	int						m_iterNdx;
};

class FragCoordXYZCase : public TestCase
{
public:
	FragCoordXYZCase (Context& context)
		: TestCase(context, "fragcoord_xyz", "gl_FragCoord.xyz Test")
	{
	}

	IterateResult iterate (void)
	{
		TestLog&				log			= m_testCtx.getLog();
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const int				width		= m_context.getRenderTarget().getWidth();
		const int				height		= m_context.getRenderTarget().getHeight();
		const tcu::RGBA			threshold	= tcu::RGBA(1,1,1,1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();
		const tcu::Vec3			scale		(1.f / float(width), 1.f / float(height), 1.0f);

		tcu::Surface			testImg		(width, height);
		tcu::Surface			refImg		(width, height);

		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
			"attribute highp vec4 a_position;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"}\n",

			"uniform mediump vec3 u_scale;\n"
			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(gl_FragCoord.xyz*u_scale, 1.0);\n"
			"}\n"));

		log << program;

		if (!program.isOk())
			throw tcu::TestError("Compile failed");

		// Draw with GL.
		{
			const float positions[] =
			{
				-1.0f,  1.0f, -1.0f, 1.0f,
				-1.0f, -1.0f,  0.0f, 1.0f,
				 1.0f,  1.0f,  0.0f, 1.0f,
				 1.0f, -1.0f,  1.0f, 1.0f
			};
			const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };

			const int				scaleLoc	= gl.getUniformLocation(program.getProgram(), "u_scale");
			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_position", 4, 4, 0, &positions[0]);

			gl.useProgram(program.getProgram());
			gl.uniform3fv(scaleLoc, 1, scale.getPtr());

			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));

			glu::readPixels(m_context.getRenderContext(), 0, 0, testImg.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
		}

		// Draw reference
		for (int y = 0; y < refImg.getHeight(); y++)
		{
			for (int x = 0; x < refImg.getWidth(); x++)
			{
				const float			xf			= (float(x)+.5f) / float(refImg.getWidth());
				const float			yf			= (float(refImg.getHeight()-y-1)+.5f) / float(refImg.getHeight());
				const float			z			= (xf + yf) / 2.0f;
				const tcu::Vec3		fragCoord	(float(x)+.5f, float(y)+.5f, z);
				const tcu::Vec3		scaledFC	= fragCoord*scale;
				const tcu::Vec4		color		(scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);

				refImg.setPixel(x, y, tcu::RGBA(color));
			}
		}

		// Compare
		{
			bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
									isOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}
};

static inline float projectedTriInterpolate (const tcu::Vec3& s, const tcu::Vec3& w, float nx, float ny)
{
	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]);
}

class FragCoordWCase : public TestCase
{
public:
	FragCoordWCase (Context& context)
		: TestCase(context, "fragcoord_w", "gl_FragCoord.w Test")
	{
	}

	IterateResult iterate (void)
	{
		TestLog&				log			= m_testCtx.getLog();
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const int				width		= m_context.getRenderTarget().getWidth();
		const int				height		= m_context.getRenderTarget().getHeight();
		const tcu::RGBA			threshold	= tcu::RGBA(1,1,1,1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();

		tcu::Surface			testImg		(width, height);
		tcu::Surface			refImg		(width, height);

		const float				w[4]		= { 1.7f, 2.0f, 1.2f, 1.0f };

		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
			"attribute highp vec4 a_position;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"}\n",

			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0, 1.0/gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
			"}\n"));

		log << program;

		if (!program.isOk())
			throw tcu::TestError("Compile failed");

		// Draw with GL.
		{
			const float positions[] =
			{
				-w[0],  w[0], 0.0f, w[0],
				-w[1], -w[1], 0.0f, w[1],
				 w[2],  w[2], 0.0f, w[2],
				 w[3], -w[3], 0.0f, w[3]
			};
			const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };

			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_position", 4, 4, 0, &positions[0]);

			gl.useProgram(program.getProgram());

			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));

			glu::readPixels(m_context.getRenderContext(), 0, 0, testImg.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
		}

		// Draw reference
		for (int y = 0; y < refImg.getHeight(); y++)
		{
			for (int x = 0; x < refImg.getWidth(); x++)
			{
				const float			xf			= (float(x)+.5f) / float(refImg.getWidth());
				const float			yf			= (float(refImg.getHeight()-y-1)+.5f) / float(refImg.getHeight());
				const float			oow			= ((xf + yf) < 1.0f)
												? projectedTriInterpolate(tcu::Vec3(w[0], w[1], w[2]), tcu::Vec3(w[0], w[1], w[2]), xf, yf)
												: projectedTriInterpolate(tcu::Vec3(w[3], w[2], w[1]), tcu::Vec3(w[3], w[2], w[1]), 1.0f-xf, 1.0f-yf);
				const tcu::Vec4		color		(0.0f, oow - 1.0f, 0.0f, 1.0f);

				refImg.setPixel(x, y, tcu::RGBA(color));
			}
		}

		// Compare
		{
			bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
									isOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}
};

class PointCoordCase : public TestCase
{
public:
	PointCoordCase (Context& context)
		: TestCase(context, "pointcoord", "gl_PointCoord Test")
	{
	}

	IterateResult iterate (void)
	{
		TestLog&				log			= m_testCtx.getLog();
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const int				width		= de::min(256, m_context.getRenderTarget().getWidth());
		const int				height		= de::min(256, m_context.getRenderTarget().getHeight());
		const float				threshold	= 0.02f;

		const int				numPoints	= 8;

		vector<tcu::Vec3>		coords		(numPoints);
		float					pointSizeRange[2]	= { 0.0f, 0.0f };

		de::Random				rnd			(0x145fa);
		tcu::Surface			testImg		(width, height);
		tcu::Surface			refImg		(width, height);

		gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, &pointSizeRange[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE)");

		if (pointSizeRange[0] <= 0.0f || pointSizeRange[1] <= 0.0f || pointSizeRange[1] < pointSizeRange[0])
			throw tcu::TestError("Invalid GL_ALIASED_POINT_SIZE_RANGE");

		// Compute coordinates.
		{

			for (vector<tcu::Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
			{
				coord->x() = rnd.getFloat(-0.9f, 0.9f);
				coord->y() = rnd.getFloat(-0.9f, 0.9f);
				coord->z() = rnd.getFloat(pointSizeRange[0], pointSizeRange[1]);
			}
		}

		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
			"attribute highp vec3 a_positionSize;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(a_positionSize.xy, 0.0, 1.0);\n"
			"	gl_PointSize = a_positionSize.z;\n"
			"}\n",

			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(gl_PointCoord, 0.0, 1.0);\n"
			"}\n"));

		log << program;

		if (!program.isOk())
			throw tcu::TestError("Compile failed");

		// Draw with GL.
		{
			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_positionSize", 3, (int)coords.size(), 0, (const float*)&coords[0]);
			const int				viewportX	= rnd.getInt(0, m_context.getRenderTarget().getWidth()-width);
			const int				viewportY	= rnd.getInt(0, m_context.getRenderTarget().getHeight()-height);

			gl.viewport(viewportX, viewportY, width, height);
			gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
			gl.clear(GL_COLOR_BUFFER_BIT);

			gl.useProgram(program.getProgram());

			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
					  glu::pr::Points((int)coords.size()));

			glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
		}

		// Draw reference
		tcu::clear(refImg.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
		for (vector<tcu::Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
		{
			const int	x0		= deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) - pointIter->z()*0.5f);
			const int	y0		= deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) - pointIter->z()*0.5f);
			const int	x1		= deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) + pointIter->z()*0.5f);
			const int	y1		= deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) + pointIter->z()*0.5f);
			const int	w		= x1-x0;
			const int	h		= y1-y0;

			for (int yo = 0; yo < h; yo++)
			{
				for (int xo = 0; xo < w; xo++)
				{
					const float			xf		= (float(xo)+0.5f) / float(w);
					const float			yf		= (float(h-yo-1)+0.5f) / float(h);
					const tcu::Vec4		color	(xf, yf, 0.0f, 1.0f);
					const int			dx		= x0+xo;
					const int			dy		= y0+yo;

					if (de::inBounds(dx, 0, refImg.getWidth()) && de::inBounds(dy, 0, refImg.getHeight()))
						refImg.setPixel(dx, dy, tcu::RGBA(color));
				}
			}
		}

		// Compare
		{
			bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
									isOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}
};

class FrontFacingCase : public TestCase
{
public:
	FrontFacingCase (Context& context)
		: TestCase(context, "frontfacing", "gl_FrontFacing Test")
	{
	}

	IterateResult iterate (void)
	{
		// Test case renders two adjecent quads, where left is has front-facing
		// triagles and right back-facing. Color is selected based on gl_FrontFacing
		// value.

		TestLog&				log			= m_testCtx.getLog();
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		de::Random				rnd			(0x89f2c);
		const int				width		= de::min(64, m_context.getRenderTarget().getWidth());
		const int				height		= de::min(64, m_context.getRenderTarget().getHeight());
		const int				viewportX	= rnd.getInt(0, m_context.getRenderTarget().getWidth()-width);
		const int				viewportY	= rnd.getInt(0, m_context.getRenderTarget().getHeight()-height);
		const tcu::RGBA			threshold	= tcu::RGBA(1,1,1,1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();

		tcu::Surface			testImg		(width, height);
		tcu::Surface			refImg		(width, height);

		const glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(
			"attribute highp vec4 a_position;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"}\n",

			"void main (void)\n"
			"{\n"
			"	if (gl_FrontFacing)\n"
			"		gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
			"	else\n"
			"		gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
			"}\n"));

		log << program;

		if (!program.isOk())
			throw tcu::TestError("Compile failed");

		// Draw with GL.
		{
			const float positions[] =
			{
				-1.0f,  1.0f, 0.0f, 1.0f,
				-1.0f, -1.0f, 0.0f, 1.0f,
				 1.0f,  1.0f, 0.0f, 1.0f,
				 1.0f, -1.0f, 0.0f, 1.0f
			};
			const deUint16 indicesCCW[]	= { 0, 1, 2, 2, 1, 3 };
			const deUint16 indicesCW[]	= { 2, 1, 0, 3, 1, 2 };

			glu::VertexArrayBinding	posBinding	= glu::va::Float("a_position", 4, 4, 0, &positions[0]);

			gl.useProgram(program.getProgram());

			gl.viewport(viewportX, viewportY, width/2, height);
			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCCW), &indicesCCW[0]));

			gl.viewport(viewportX + width/2, viewportY, width-width/2, height);
			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCW), &indicesCW[0]));

			glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
		}

		// Draw reference
		for (int y = 0; y < refImg.getHeight(); y++)
		{
			for (int x = 0; x < refImg.getWidth()/2; x++)
				refImg.setPixel(x, y, tcu::RGBA::green());

			for (int x = refImg.getWidth()/2; x < refImg.getWidth(); x++)
				refImg.setPixel(x, y, tcu::RGBA::blue());
		}

		// Compare
		{
			bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold, tcu::COMPARE_LOG_RESULT);
			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
									isOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}
};

ShaderBuiltinVarTests::ShaderBuiltinVarTests (Context& context)
	: TestCaseGroup(context, "builtin_variable", "Built-in Variable Tests")
{
}

ShaderBuiltinVarTests::~ShaderBuiltinVarTests (void)
{
}

void ShaderBuiltinVarTests::init (void)
{
	// Builtin constants.

	static const struct
	{
		const char*		caseName;
		const char*		varName;
		deUint32		paramName;
	} builtinConstants[] =
	{
		{ "max_vertex_attribs",					"gl_MaxVertexAttribs",				GL_MAX_VERTEX_ATTRIBS },
		{ "max_vertex_uniform_vectors",			"gl_MaxVertexUniformVectors",		GL_MAX_VERTEX_UNIFORM_VECTORS },
		{ "max_fragment_uniform_vectors",		"gl_MaxFragmentUniformVectors",		GL_MAX_FRAGMENT_UNIFORM_VECTORS },
		{ "max_varying_vectors",				"gl_MaxVaryingVectors",				GL_MAX_VARYING_VECTORS },
		{ "max_texture_image_units",			"gl_MaxTextureImageUnits",			GL_MAX_TEXTURE_IMAGE_UNITS },
		{ "max_vertex_texture_image_units",		"gl_MaxVertexTextureImageUnits",	GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
		{ "max_combined_texture_image_units",	"gl_MaxCombinedTextureImageUnits",	GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
		{ "max_draw_buffers",					"gl_MaxDrawBuffers",				GL_NONE }
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtinConstants); ndx++)
	{
		const char*		caseName	= builtinConstants[ndx].caseName;
		const char*		varName		= builtinConstants[ndx].varName;
		deUint32		paramName	= builtinConstants[ndx].paramName;

		addChild(new ShaderBuiltinConstantCase(m_context, (string(caseName) + "_vertex").c_str(),	varName, varName, paramName, true));
		addChild(new ShaderBuiltinConstantCase(m_context, (string(caseName) + "_fragment").c_str(),	varName, varName, paramName, false));
	}

	addChild(new ShaderDepthRangeTest(m_context, "depth_range_vertex",		"gl_DepthRange", true));
	addChild(new ShaderDepthRangeTest(m_context, "depth_range_fragment",	"gl_DepthRange", false));

	// Fragment shader builtin variables.

	addChild(new FragCoordXYZCase	(m_context));
	addChild(new FragCoordWCase		(m_context));
	addChild(new PointCoordCase		(m_context));
	addChild(new FrontFacingCase	(m_context));
}

} // Functional
} // gles2
} // deqp
