/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.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 Polygon offset tests.
 *//*--------------------------------------------------------------------*/

#include "es3fPolygonOffsetTests.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "gluContextInfo.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"
#include "glwEnums.hpp"
#include "glwDefs.hpp"
#include "glwFunctions.hpp"
#include "tcuTestContext.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuVectorUtil.hpp"
#include "rrRenderer.hpp"
#include "rrFragmentOperations.hpp"

#include "sglrReferenceContext.hpp"

#include <string>
#include <limits>

using namespace glw; // GLint and other GL types

namespace deqp
{
namespace gles3
{
namespace Functional
{
namespace
{

const char* s_shaderSourceVertex	= "#version 300 es\n"
									  "in highp vec4 a_position;\n"
									  "in highp vec4 a_color;\n"
									  "out highp vec4 v_color;\n"
									  "void main (void)\n"
									  "{\n"
									  "	gl_Position = a_position;\n"
									  "	v_color = a_color;\n"
									  "}\n";
const char* s_shaderSourceFragment	= "#version 300 es\n"
									  "in highp vec4 v_color;\n"
									  "layout(location = 0) out mediump vec4 fragColor;"
									  "void main (void)\n"
									  "{\n"
									  "	fragColor = v_color;\n"
									  "}\n";

static const tcu::Vec4	MASK_COLOR_OK	= tcu::Vec4(0.0f, 0.1f, 0.0f, 1.0f);
static const tcu::Vec4	MASK_COLOR_DEV	= tcu::Vec4(0.8f, 0.5f, 0.0f, 1.0f);
static const tcu::Vec4	MASK_COLOR_FAIL	= tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);

inline bool compareThreshold (const tcu::IVec4& a, const tcu::IVec4& b, const tcu::IVec4& threshold)
{
	return tcu::boolAll(tcu::lessThanEqual(tcu::abs(a - b), threshold));
}

/*--------------------------------------------------------------------*//*!
* \brief Pixelwise comparison of two images.
* \note copied & modified from glsRasterizationTests
*
* Kernel radius defines maximum allowed distance. If radius is 0, only
* perfect match is allowed. Radius of 1 gives a 3x3 kernel.
*
* Return values: -1 = Perfect match
* 0 = Deviation within kernel
* >0 = Number of faulty pixels
*//*--------------------------------------------------------------------*/
int compareImages (tcu::TestLog& log, glu::RenderContext& renderCtx, const tcu::ConstPixelBufferAccess& test, const tcu::ConstPixelBufferAccess& ref, const tcu::PixelBufferAccess& diffMask, int radius)
{
	const int			height			= test.getHeight();
	const int			width			= test.getWidth();
	const int			colorThreshold	= 128;
	const tcu::RGBA		formatThreshold	= renderCtx.getRenderTarget().getPixelFormat().getColorThreshold();
	const tcu::IVec4	threshold		= tcu::IVec4(colorThreshold, colorThreshold, colorThreshold, formatThreshold.getAlpha() > 0 ? colorThreshold : 0)
										+ tcu::IVec4(formatThreshold.getRed(), formatThreshold.getGreen(), formatThreshold.getBlue(), formatThreshold.getAlpha());

	int			deviatingPixels = 0;
	int			faultyPixels	= 0;
	int			compareFailed	= -1;

	tcu::clear(diffMask, MASK_COLOR_OK);

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			const tcu::IVec4 cRef = ref.getPixelInt(x, y);

			// Pixelwise match, no deviation or fault
			{
				const tcu::IVec4 cTest = test.getPixelInt(x, y);
				if (compareThreshold(cRef, cTest, threshold))
					continue;
			}

			// If not, search within kernel radius
			{
				const int kYmin = deMax32(y - radius, 0);
				const int kYmax = deMin32(y + radius, height-1);
				const int kXmin = deMax32(x - radius, 0);
				const int kXmax = deMin32(x + radius, width-1);
				bool found = false;

				for (int kY = kYmin; kY <= kYmax; kY++)
				for (int kX = kXmin; kX <= kXmax; kX++)
				{
					const tcu::IVec4 cTest = test.getPixelInt(kX, kY);
					if (compareThreshold(cRef, cTest, threshold))
						found = true;
				}

				if (found)	// The pixel is deviating if the color is found inside the kernel
				{
					diffMask.setPixel(MASK_COLOR_DEV, x, y);
					if (compareFailed == -1)
						compareFailed = 0;
					deviatingPixels++;
					continue;
				}
			}

			diffMask.setPixel(MASK_COLOR_FAIL, x, y);
			faultyPixels++;										// The pixel is faulty if the color is not found
			compareFailed = 1;
		}
	}

	log << tcu::TestLog::Message << faultyPixels << " faulty pixel(s) found." << tcu::TestLog::EndMessage;

	return (compareFailed == 1 ? faultyPixels : compareFailed);
}

void verifyImages (tcu::TestLog& log, tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const tcu::ConstPixelBufferAccess& testImage, const tcu::ConstPixelBufferAccess& referenceImage)
{
	using tcu::TestLog;

	const int			kernelRadius		= 1;
	const int			faultyPixelLimit	= 20;
	int					faultyPixels;
	tcu::Surface		diffMask			(testImage.getWidth(), testImage.getHeight());

	faultyPixels = compareImages(log, renderCtx, referenceImage, testImage, diffMask.getAccess(), kernelRadius);

	if (faultyPixels > faultyPixelLimit)
	{
		log << TestLog::ImageSet("Images", "Image comparison");
		log << TestLog::Image("Test image", "Test image", testImage);
		log << TestLog::Image("Reference image", "Reference image", referenceImage);
		log << TestLog::Image("Difference mask", "Difference mask", diffMask.getAccess());
		log << TestLog::EndImageSet;

		log << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
	}
}

void verifyError (tcu::TestContext& testCtx, const glw::Functions& gl, GLenum expected)
{
	deUint32 got = gl.getError();
	if (got != expected)
	{
		testCtx.getLog() << tcu::TestLog::Message << "// ERROR: expected " << glu::getErrorStr(expected) << "; got " << glu::getErrorStr(got) << tcu::TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error");
	}
}

void checkCanvasSize (int width, int height, int minWidth, int minHeight)
{
	if (width < minWidth || height < minHeight)
		throw tcu::NotSupportedError(std::string("Render context size must be at least ") + de::toString(minWidth) + "x" + de::toString(minWidth));
}

class PositionColorShader : public sglr::ShaderProgram
{
public:
	enum
	{
		VARYINGLOC_COLOR = 0
	};

			PositionColorShader (void);
	void	shadeVertices		(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void	shadeFragments		(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;
};

PositionColorShader::PositionColorShader (void)
	: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
							<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::VertexSource(s_shaderSourceVertex)
							<< sglr::pdec::FragmentSource(s_shaderSourceFragment))
{
}

void PositionColorShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
{
	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
	{
		const int positionAttrLoc = 0;
		const int colorAttrLoc = 1;

		rr::VertexPacket& packet = *packets[packetNdx];

		// Transform to position
		packet.position = rr::readVertexAttribFloat(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx);

		// Pass color to FS
		packet.outputs[VARYINGLOC_COLOR] = rr::readVertexAttribFloat(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx);
	}
}

void PositionColorShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
{
	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
	{
		rr::FragmentPacket& packet = packets[packetNdx];

		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readTriangleVarying<float>(packet, context, VARYINGLOC_COLOR, fragNdx));
	}
}

// PolygonOffsetTestCase

class PolygonOffsetTestCase : public TestCase
{
public:
					PolygonOffsetTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName, int canvasSize);

	virtual void	testPolygonOffset		(void) = DE_NULL;
	IterateResult	iterate					(void);

protected:
	const GLenum	m_internalFormat;
	const char*		m_internalFormatName;
	const int		m_targetSize;
};

PolygonOffsetTestCase::PolygonOffsetTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName, int canvasSize)
	: TestCase				(context, name, description)
	, m_internalFormat		(internalFormat)
	, m_internalFormatName	(internalFormatName)
	, m_targetSize			(canvasSize)
{
}

PolygonOffsetTestCase::IterateResult PolygonOffsetTestCase::iterate (void)
{
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	m_testCtx.getLog() << tcu::TestLog::Message << "Testing PolygonOffset with " << m_internalFormatName << " depth buffer." << tcu::TestLog::EndMessage;

	if (m_internalFormat == 0)
	{
		// default framebuffer
		const int width		= m_context.getRenderTarget().getWidth();
		const int height	= m_context.getRenderTarget().getHeight();

		checkCanvasSize(width, height, m_targetSize, m_targetSize);

		if (m_context.getRenderTarget().getDepthBits() == 0)
			throw tcu::NotSupportedError("polygon offset tests require depth buffer");

		testPolygonOffset();
	}
	else
	{
		const glw::Functions& gl = m_context.getRenderContext().getFunctions();

		// framebuffer object
		GLuint	colorRboId	= 0;
		GLuint	depthRboId	= 0;
		GLuint	fboId		= 0;
		bool	fboComplete;

		gl.genRenderbuffers(1, &colorRboId);
		gl.bindRenderbuffer(GL_RENDERBUFFER, colorRboId);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, m_targetSize, m_targetSize);
		verifyError(m_testCtx, gl, GL_NO_ERROR);

		gl.genRenderbuffers(1, &depthRboId);
		gl.bindRenderbuffer(GL_RENDERBUFFER, depthRboId);
		gl.renderbufferStorage(GL_RENDERBUFFER, m_internalFormat, m_targetSize, m_targetSize);
		verifyError(m_testCtx, gl, GL_NO_ERROR);

		gl.genFramebuffers(1, &fboId);
		gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRboId);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,	GL_RENDERBUFFER, depthRboId);
		verifyError(m_testCtx, gl, GL_NO_ERROR);

		fboComplete = gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;

		if (fboComplete)
			testPolygonOffset();

		gl.deleteFramebuffers(1, &fboId);
		gl.deleteRenderbuffers(1, &depthRboId);
		gl.deleteRenderbuffers(1, &colorRboId);

		if (!fboComplete)
			throw tcu::NotSupportedError("could not create fbo for testing.");
	}

	return STOP;
}

// UsageTestCase

class UsageTestCase : public PolygonOffsetTestCase
{
public:
			UsageTestCase		(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);

	void	testPolygonOffset	(void);
};

UsageTestCase::UsageTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
{
}

void UsageTestCase::testPolygonOffset (void)
{
	using tcu::TestLog;

	const tcu::Vec4 triangle[] =
	{
		tcu::Vec4(-1,  1,  0,  1),
		tcu::Vec4( 1,  1,  0,  1),
		tcu::Vec4( 1, -1,  0,  1),
	};

	tcu::TestLog&		log				= m_testCtx.getLog();
	tcu::Surface		testImage		(m_targetSize, m_targetSize);
	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);

	// render test image
	{
		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");

		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Shader compile failed.");
		}

		gl.clearColor				(0, 0, 0, 1);
		gl.clearDepthf				(1.0f);
		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gl.viewport					(0, 0, m_targetSize, m_targetSize);
		gl.useProgram				(program.getProgram());
		gl.enable					(GL_DEPTH_TEST);
		gl.depthFunc				(GL_LEQUAL);	// make test pass if polygon offset doesn't do anything. It has its own test case. This test is only for to detect always-on cases.

		log << TestLog::Message << "DepthFunc = GL_LEQUAL" << TestLog::EndMessage;

		gl.enableVertexAttribArray	(positionLoc);
		gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);

		//draw back (offset disabled)

		log << TestLog::Message << "Draw bottom-right. Color = White.\tState: PolygonOffset(0, -2), POLYGON_OFFSET_FILL disabled." << TestLog::EndMessage;

		gl.polygonOffset			(0, -2);
		gl.disable					(GL_POLYGON_OFFSET_FILL);
		gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
		gl.drawArrays				(GL_TRIANGLES, 0, 3);

		//draw front

		log << TestLog::Message << "Draw bottom-right. Color = Red.\tState: PolygonOffset(0, -1), POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;

		gl.polygonOffset			(0, -1);
		gl.enable					(GL_POLYGON_OFFSET_FILL);
		gl.vertexAttrib4f			(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
		gl.drawArrays				(GL_TRIANGLES, 0, 3);

		gl.disableVertexAttribArray	(positionLoc);
		gl.useProgram				(0);
		gl.finish					();

		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
	}

	// render reference image
	{
		rr::Renderer		referenceRenderer;
		rr::VertexAttrib	attribs[2];
		rr::RenderState		state((rr::ViewportState)(rr::WindowRectangle(0, 0, m_targetSize, m_targetSize)));

		PositionColorShader program;

		attribs[0].type				= rr::VERTEXATTRIBTYPE_FLOAT;
		attribs[0].size				= 4;
		attribs[0].stride			= 0;
		attribs[0].instanceDivisor	= 0;
		attribs[0].pointer			= triangle;

		attribs[1].type				= rr::VERTEXATTRIBTYPE_DONT_CARE;
		attribs[1].generic			= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);

		tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

		log << TestLog::Message << "Expecting: Bottom-right = Red." << TestLog::EndMessage;

		referenceRenderer.draw(
			rr::DrawCommand(
				state,
				rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())),
				rr::Program(program.getVertexShader(), program.getFragmentShader()),
				2,
				attribs,
				rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0)));
	}

	// compare
	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
}

// UsageDisplacementTestCase

class UsageDisplacementTestCase : public PolygonOffsetTestCase
{
public:
				UsageDisplacementTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);

private:
	tcu::Vec4	genRandomVec4				(de::Random& rnd) const;
	void		testPolygonOffset			(void);
};

UsageDisplacementTestCase::UsageDisplacementTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
{
}

tcu::Vec4 UsageDisplacementTestCase::genRandomVec4 (de::Random& rnd) const
{
	// generater triangle endpoint with following properties
	//	1) it will not be clipped
	//	2) it is not near either far or near plane to prevent possible problems related to depth clamping
	// => w >= 1.0 and z in (-0.9, 0.9) range
	tcu::Vec4 retVal;

	retVal.x() = rnd.getFloat(-1, 1);
	retVal.y() = rnd.getFloat(-1, 1);
	retVal.z() = rnd.getFloat(-0.9f, 0.9f);
	retVal.w() = 1.0f + rnd.getFloat();

	return retVal;
}

void UsageDisplacementTestCase::testPolygonOffset (void)
{
	using tcu::TestLog;

	de::Random			rnd				(0xdec0de);
	tcu::TestLog&		log				= m_testCtx.getLog();
	tcu::Surface		testImage		(m_targetSize, m_targetSize);
	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);

	// render test image
	{
		const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
		const GLint					positionLoc		= gl.getAttribLocation(program.getProgram(), "a_position");
		const GLint					colorLoc		= gl.getAttribLocation(program.getProgram(), "a_color");
		const int					numIterations	= 40;

		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Shader compile failed.");
		}

		gl.clearColor				(0, 0, 0, 1);
		gl.clearDepthf				(1.0f);
		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gl.viewport					(0, 0, m_targetSize, m_targetSize);
		gl.useProgram				(program.getProgram());
		gl.enable					(GL_DEPTH_TEST);
		gl.enable					(GL_POLYGON_OFFSET_FILL);
		gl.enableVertexAttribArray	(positionLoc);
		gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);

		log << TestLog::Message << "Framebuffer cleared, clear color = Black." << TestLog::EndMessage;
		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;

		// draw colorless (mask = 0,0,0) triangle at random* location, set offset and render green triangle with depthfunc = equal
		// *) w >= 1.0 and z in (-1, 1) range
		for (int iterationNdx = 0; iterationNdx < numIterations; ++iterationNdx)
		{
			const bool		offsetDirection = rnd.getBool();
			const float		offset = offsetDirection ? -1.0f : 1.0f;
			tcu::Vec4		triangle[3];

			for (int vertexNdx = 0; vertexNdx < DE_LENGTH_OF_ARRAY(triangle); ++vertexNdx)
				triangle[vertexNdx] = genRandomVec4(rnd);

			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);

			log << TestLog::Message << "Setup triangle with random coordinates:" << TestLog::EndMessage;
			for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangle); ++ndx)
				log << TestLog::Message
						<< "\tx=" << triangle[ndx].x()
						<< "\ty=" << triangle[ndx].y()
						<< "\tz=" << triangle[ndx].z()
						<< "\tw=" << triangle[ndx].w()
						<< TestLog::EndMessage;

			log << TestLog::Message << "Draw colorless triangle.\tState: DepthFunc = GL_ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_ALWAYS);
			gl.polygonOffset			(0, 0);
			gl.colorMask				(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			// all fragments should have different Z => DepthFunc == GL_EQUAL fails with every fragment

			log << TestLog::Message << "Draw green triangle.\tState: DepthFunc = GL_EQUAL, PolygonOffset(0, " << offset << ")." << TestLog::EndMessage;

			gl.depthFunc				(GL_EQUAL);
			gl.polygonOffset			(0, offset);
			gl.colorMask				(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << TestLog::EndMessage; // empty line for clarity
		}

		gl.disableVertexAttribArray	(positionLoc);
		gl.useProgram				(0);
		gl.finish					();

		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
	}

	// render reference image
	log << TestLog::Message << "Expecting black framebuffer." << TestLog::EndMessage;
	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	// compare
	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
}

// UsagePositiveNegativeTestCase

class UsagePositiveNegativeTestCase : public PolygonOffsetTestCase
{
public:
			UsagePositiveNegativeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);

	void	testPolygonOffset				(void);
};

UsagePositiveNegativeTestCase::UsagePositiveNegativeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
{
}

void UsagePositiveNegativeTestCase::testPolygonOffset (void)
{
	using tcu::TestLog;

	const tcu::Vec4 triangleBottomRight[] =
	{
		tcu::Vec4(-1,  1,  0,  1),
		tcu::Vec4( 1,  1,  0,  1),
		tcu::Vec4( 1, -1,  0,  1),
	};
	const tcu::Vec4 triangleTopLeft[] =
	{
		tcu::Vec4(-1, -1,  0,  1),
		tcu::Vec4(-1,  1,  0,  1),
		tcu::Vec4( 1, -1,  0,  1),
	};

	tcu::TestLog&		log				= m_testCtx.getLog();
	tcu::Surface		testImage		(m_targetSize, m_targetSize);
	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);

	// render test image
	{
		const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
		const GLint					positionLoc		= gl.getAttribLocation(program.getProgram(), "a_position");
		const GLint					colorLoc		= gl.getAttribLocation(program.getProgram(), "a_color");

		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Shader compile failed.");
		}

		gl.clearColor				(0, 0, 0, 1);
		gl.clearDepthf				(1.0f);
		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gl.viewport					(0, 0, m_targetSize, m_targetSize);
		gl.depthFunc				(GL_LESS);
		gl.useProgram				(program.getProgram());
		gl.enable					(GL_DEPTH_TEST);
		gl.enable					(GL_POLYGON_OFFSET_FILL);
		gl.enableVertexAttribArray	(positionLoc);

		log << TestLog::Message << "DepthFunc = GL_LESS." << TestLog::EndMessage;
		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;

		//draw top left (negative offset test)
		{
			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft);

			log << TestLog::Message << "Draw top-left. Color = White.\tState: PolygonOffset(0, 0)." << TestLog::EndMessage;

			gl.polygonOffset			(0, 0);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << "Draw top-left. Color = Green.\tState: PolygonOffset(0, -1)." << TestLog::EndMessage;

			gl.polygonOffset			(0, -1);
			gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);
		}

		//draw bottom right (positive offset test)
		{
			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight);

			log << TestLog::Message << "Draw bottom-right. Color = White.\tState: PolygonOffset(0, 1)." << TestLog::EndMessage;

			gl.polygonOffset			(0, 1);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << "Draw bottom-right. Color = Yellow.\tState: PolygonOffset(0, 0)." << TestLog::EndMessage;

			gl.polygonOffset			(0, 0);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);
		}

		gl.disableVertexAttribArray	(positionLoc);
		gl.useProgram				(0);
		gl.finish					();

		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
	}

	// render reference image
	{
		rr::Renderer		referenceRenderer;
		rr::VertexAttrib	attribs[2];
		rr::RenderState		state((rr::ViewportState)(rr::WindowRectangle(0, 0, m_targetSize, m_targetSize)));

		PositionColorShader program;

		attribs[0].type				= rr::VERTEXATTRIBTYPE_FLOAT;
		attribs[0].size				= 4;
		attribs[0].stride			= 0;
		attribs[0].instanceDivisor	= 0;
		attribs[0].pointer			= triangleTopLeft;

		attribs[1].type				= rr::VERTEXATTRIBTYPE_DONT_CARE;
		attribs[1].generic			= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);

		tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

		log << TestLog::Message << "Expecting: Top-left = Green, Bottom-right = Yellow." << TestLog::EndMessage;

		referenceRenderer.draw(
			rr::DrawCommand(
				state,
				rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())),
				rr::Program(program.getVertexShader(), program.getFragmentShader()),
				2,
				attribs,
				rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0)));

		attribs[0].pointer = triangleBottomRight;
		attribs[1].generic = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);

		referenceRenderer.draw(
			rr::DrawCommand(
				state,
				rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceImage.getAccess())),
				rr::Program(program.getVertexShader(), program.getFragmentShader()),
				2,
				attribs,
				rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, 3, 0)));
	}

	// compare
	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
}

// ResultClampingTestCase

class ResultClampingTestCase : public PolygonOffsetTestCase
{
public:
			ResultClampingTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);

	void	testPolygonOffset		(void);
};

ResultClampingTestCase::ResultClampingTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
{
}

void ResultClampingTestCase::testPolygonOffset (void)
{
	using tcu::TestLog;

	const tcu::Vec4 triangleBottomRight[] =
	{
		tcu::Vec4(-1,  1,  1,  1),
		tcu::Vec4( 1,  1,  1,  1),
		tcu::Vec4( 1, -1,  1,  1),
	};
	const tcu::Vec4 triangleTopLeft[] =
	{
		tcu::Vec4(-1, -1, -1,  1),
		tcu::Vec4(-1,  1, -1,  1),
		tcu::Vec4( 1, -1, -1,  1),
	};

	tcu::TestLog&		log				= m_testCtx.getLog();
	tcu::Surface		testImage		(m_targetSize, m_targetSize);
	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);

	// render test image
	{
		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");

		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Shader compile failed.");
		}

		gl.clearColor				(0, 0, 0, 1);
		gl.clearDepthf				(1.0f);
		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gl.viewport					(0, 0, m_targetSize, m_targetSize);
		gl.useProgram				(program.getProgram());
		gl.enable					(GL_DEPTH_TEST);
		gl.enable					(GL_POLYGON_OFFSET_FILL);
		gl.enableVertexAttribArray	(positionLoc);

		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;

		//draw bottom right (far)
		{
			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight);

			log << TestLog::Message << "Draw bottom-right. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 8), Polygon Z = 1.0. (Result depth should clamp to 1.0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_ALWAYS);
			gl.polygonOffset			(0, 8);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << "Draw bottom-right. Color = Red.\tState: DepthFunc = GREATER, PolygonOffset(0, 9), Polygon Z = 1.0. (Result depth should clamp to 1.0 too)" << TestLog::EndMessage;

			gl.depthFunc				(GL_GREATER);
			gl.polygonOffset			(0, 9);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);
		}

		//draw top left (near)
		{
			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft);

			log << TestLog::Message << "Draw top-left. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, -8), Polygon Z = -1.0. (Result depth should clamp to -1.0)" << TestLog::EndMessage;

			gl.depthFunc				(GL_ALWAYS);
			gl.polygonOffset			(0, -8);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << "Draw top-left. Color = Yellow.\tState: DepthFunc = LESS, PolygonOffset(0, -9), Polygon Z = -1.0. (Result depth should clamp to -1.0 too)." << TestLog::EndMessage;

			gl.depthFunc				(GL_LESS);
			gl.polygonOffset			(0, -9);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);
		}

		gl.disableVertexAttribArray	(positionLoc);
		gl.useProgram				(0);
		gl.finish					();

		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
	}

	// render reference image
	log << TestLog::Message << "Expecting: Top-left = White, Bottom-right = White." << TestLog::EndMessage;
	tcu::clear(referenceImage.getAccess(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

	// compare
	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
}

// UsageSlopeTestCase

class UsageSlopeTestCase  : public PolygonOffsetTestCase
{
public:
			UsageSlopeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);

	void	testPolygonOffset	(void);
};

UsageSlopeTestCase::UsageSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
{
}

void UsageSlopeTestCase::testPolygonOffset (void)
{
	using tcu::TestLog;

	const tcu::Vec4 triangleBottomRight[] =
	{
		tcu::Vec4(-1,  1,  0.0f,  1),
		tcu::Vec4( 1,  1,  0.9f,  1),
		tcu::Vec4( 1, -1,  0.9f,  1),
	};
	const tcu::Vec4 triangleTopLeft[] =
	{
		tcu::Vec4(-1, -1,  -0.9f,  1),
		tcu::Vec4(-1,  1,   0.9f,  1),
		tcu::Vec4( 1, -1,   0.0f,  1),
	};

	tcu::TestLog&		log				= m_testCtx.getLog();
	tcu::Surface		testImage		(m_targetSize, m_targetSize);
	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);

	// render test image
	{
		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");

		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Shader compile failed.");
		}

		gl.clearColor				(0, 0, 0, 1);
		gl.clearDepthf				(1.0f);
		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gl.viewport					(0, 0, m_targetSize, m_targetSize);
		gl.useProgram				(program.getProgram());
		gl.enable					(GL_DEPTH_TEST);
		gl.enable					(GL_POLYGON_OFFSET_FILL);
		gl.enableVertexAttribArray	(positionLoc);

		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;

		//draw top left (negative offset test)
		{
			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleTopLeft);

			log << TestLog::Message << "Draw top-left. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_ALWAYS);
			gl.polygonOffset			(0, 0);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << "Draw top-left. Color = Green.\tState: DepthFunc = LESS, PolygonOffset(-1, 0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_LESS);
			gl.polygonOffset			(-1, 0);
			gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);
		}

		//draw bottom right (positive offset test)
		{
			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangleBottomRight);

			log << TestLog::Message << "Draw bottom-right. Color = White.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_ALWAYS);
			gl.polygonOffset			(0, 0);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << "Draw bottom-right. Color = Green.\tState: DepthFunc = GREATER, PolygonOffset(1, 0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_GREATER);
			gl.polygonOffset			(1, 0);
			gl.vertexAttrib4f			(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);
		}

		gl.disableVertexAttribArray	(positionLoc);
		gl.useProgram				(0);
		gl.finish					();

		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
	}

	// render reference image
	log << TestLog::Message << "Expecting: Top-left = Green, Bottom-right = Green." << TestLog::EndMessage;
	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));

	// compare
	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
}

// ZeroSlopeTestCase

class ZeroSlopeTestCase : public PolygonOffsetTestCase
{
public:
			ZeroSlopeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);

	void	testPolygonOffset	(void);
};

ZeroSlopeTestCase::ZeroSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
{
}

void ZeroSlopeTestCase::testPolygonOffset (void)
{
	using tcu::TestLog;

	const tcu::Vec4 triangle[] =
	{
		tcu::Vec4(-0.4f,  0.4f, 0.0f, 1.0f),
		tcu::Vec4(-0.8f, -0.5f, 0.0f, 1.0f),
		tcu::Vec4( 0.7f,  0.2f, 0.0f, 1.0f),
	};

	tcu::TestLog&		log				= m_testCtx.getLog();
	tcu::Surface		testImage		(m_targetSize, m_targetSize);
	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);

	// log the triangle
	log << TestLog::Message << "Setup triangle with coordinates:" << TestLog::EndMessage;
	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangle); ++ndx)
		log << TestLog::Message
				<< "\tx=" << triangle[ndx].x()
				<< "\ty=" << triangle[ndx].y()
				<< "\tz=" << triangle[ndx].z()
				<< "\tw=" << triangle[ndx].w()
				<< TestLog::EndMessage;

	// render test image
	{
		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");

		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Shader compile failed.");
		}

		gl.clearColor				(0, 0, 0, 1);
		gl.clearDepthf				(1.0f);
		gl.clear					(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		gl.viewport					(0, 0, m_targetSize, m_targetSize);
		gl.useProgram				(program.getProgram());
		gl.enable					(GL_DEPTH_TEST);
		gl.enable					(GL_POLYGON_OFFSET_FILL);
		gl.enableVertexAttribArray	(positionLoc);

		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;

		{
			gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);

			log << TestLog::Message << "Draw triangle. Color = Red.\tState: DepthFunc = ALWAYS, PolygonOffset(0, 0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_ALWAYS);
			gl.polygonOffset			(0, 0);
			gl.vertexAttrib4f			(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);

			log << TestLog::Message << "Draw triangle. Color = Black.\tState: DepthFunc = EQUAL, PolygonOffset(4, 0)." << TestLog::EndMessage;

			gl.depthFunc				(GL_EQUAL);
			gl.polygonOffset			(4, 0);	// triangle slope == 0
			gl.vertexAttrib4f			(colorLoc, 0.0f, 0.0f, 0.0f, 1.0f);
			gl.drawArrays				(GL_TRIANGLES, 0, 3);
		}

		gl.disableVertexAttribArray	(positionLoc);
		gl.useProgram				(0);
		gl.finish					();

		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
	}

	// render reference image
	log << TestLog::Message << "Expecting black triangle." << TestLog::EndMessage;
	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	// compare
	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
}

// OneSlopeTestCase

class OneSlopeTestCase : public PolygonOffsetTestCase
{
public:
			OneSlopeTestCase	(Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName);

	void	testPolygonOffset	(void);
};

OneSlopeTestCase::OneSlopeTestCase (Context& context, const char* name, const char* description, GLenum internalFormat, const char* internalFormatName)
	: PolygonOffsetTestCase(context, name, description, internalFormat, internalFormatName, 200)
{
}

void OneSlopeTestCase::testPolygonOffset (void)
{
	using tcu::TestLog;

	/*
		* setup vertices subject to following properties
		*   dz_w / dx_w == 1
		*   dz_w / dy_w == 0
		* or
		*   dz_w / dx_w == 0
		*   dz_w / dy_w == 1
		* ==> m == 1
		*/
	const float cornerDepth = float(m_targetSize);
	const tcu::Vec4 triangles[2][3] =
	{
		{
			tcu::Vec4(-1, -1, -cornerDepth, 1),
			tcu::Vec4(-1,  1, -cornerDepth, 1),
			tcu::Vec4( 1, -1,  cornerDepth, 1),
		},
		{
			tcu::Vec4(-1,  1,  cornerDepth, 1),
			tcu::Vec4( 1,  1,  cornerDepth, 1),
			tcu::Vec4( 1, -1, -cornerDepth, 1),
		},
	};

	tcu::TestLog&		log				= m_testCtx.getLog();
	tcu::Surface		testImage		(m_targetSize, m_targetSize);
	tcu::Surface		referenceImage	(m_targetSize, m_targetSize);

	// log triangle info
	log << TestLog::Message << "Setup triangle0 coordinates: (slope in window coordinates = 1.0)" << TestLog::EndMessage;
	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangles[0]); ++ndx)
		log << TestLog::Message
				<< "\tx=" << triangles[0][ndx].x()
				<< "\ty=" << triangles[0][ndx].y()
				<< "\tz=" << triangles[0][ndx].z()
				<< "\tw=" << triangles[0][ndx].w()
				<< TestLog::EndMessage;
	log << TestLog::Message << "Setup triangle1 coordinates: (slope in window coordinates = 1.0)" << TestLog::EndMessage;
	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(triangles[1]); ++ndx)
		log << TestLog::Message
				<< "\tx=" << triangles[1][ndx].x()
				<< "\ty=" << triangles[1][ndx].y()
				<< "\tz=" << triangles[1][ndx].z()
				<< "\tw=" << triangles[1][ndx].w()
				<< TestLog::EndMessage;

	// render test image
	{
		const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
		const glu::ShaderProgram	program		(m_context.getRenderContext(), glu::makeVtxFragSources(s_shaderSourceVertex, s_shaderSourceFragment));
		const GLint					positionLoc = gl.getAttribLocation(program.getProgram(), "a_position");
		const GLint					colorLoc	= gl.getAttribLocation(program.getProgram(), "a_color");

		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Shader compile failed.");
		}

		gl.clearColor				(0, 0, 0, 1);
		gl.clear					(GL_COLOR_BUFFER_BIT);
		gl.viewport					(0, 0, m_targetSize, m_targetSize);
		gl.useProgram				(program.getProgram());
		gl.enable					(GL_DEPTH_TEST);
		gl.enable					(GL_POLYGON_OFFSET_FILL);
		gl.enableVertexAttribArray	(positionLoc);

		log << TestLog::Message << "Framebuffer cleared, clear color = Black." << TestLog::EndMessage;
		log << TestLog::Message << "POLYGON_OFFSET_FILL enabled." << TestLog::EndMessage;

		// top left (positive offset)
		{
			log << TestLog::Message << "Clear depth to 1.0." << TestLog::EndMessage;

			gl.clearDepthf			(1.0f); // far
			gl.clear				(GL_DEPTH_BUFFER_BIT);

			gl.vertexAttribPointer	(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangles[0]);

			log << TestLog::Message << "Draw triangle0. Color = Red.\tState: DepthFunc = NOTEQUAL, PolygonOffset(10, 0). (Result depth should clamp to 1.0)." << TestLog::EndMessage;

			gl.polygonOffset		(10, 0);		// clamps any depth on the triangle to 1
			gl.depthFunc			(GL_NOTEQUAL);
			gl.vertexAttrib4f		(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
			gl.drawArrays			(GL_TRIANGLES, 0, 3);
		}
		// bottom right (negative offset)
		{
			log << TestLog::Message << "Clear depth to 0.0." << TestLog::EndMessage;

			gl.clearDepthf			(0.0f); // far
			gl.clear				(GL_DEPTH_BUFFER_BIT);

			gl.vertexAttribPointer	(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangles[1]);

			log << TestLog::Message << "Draw triangle1. Color = Green.\tState: DepthFunc = NOTEQUAL, PolygonOffset(-10, 0). (Result depth should clamp to 0.0)." << TestLog::EndMessage;

			gl.polygonOffset		(-10, 0); // clamps depth to 0
			gl.depthFunc			(GL_NOTEQUAL);
			gl.vertexAttrib4f		(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
			gl.drawArrays			(GL_TRIANGLES, 0, 3);
		}

		gl.disableVertexAttribArray	(positionLoc);
		gl.useProgram				(0);
		gl.finish					();

		glu::readPixels(m_context.getRenderContext(), 0, 0, testImage.getAccess());
	}

	// render reference image
	log << TestLog::Message << "Expecting black framebuffer." << TestLog::EndMessage;
	tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	// compare
	verifyImages(log, m_testCtx, m_context.getRenderContext(), testImage.getAccess(), referenceImage.getAccess());
}

} // anonymous

PolygonOffsetTests::PolygonOffsetTests (Context& context)
	: TestCaseGroup(context, "polygon_offset", "Polygon offset tests")
{
}

PolygonOffsetTests::~PolygonOffsetTests (void)
{
}

void PolygonOffsetTests::init (void)
{
	const struct DepthBufferFormat
	{
		enum BufferType
		{
			TYPE_FIXED_POINT,
			TYPE_FLOATING_POINT,
			TYPE_UNKNOWN
		};

		GLenum		internalFormat;
		int			bits;
		BufferType	floatingPoint;
		const char* name;
	} depthFormats[]=
	{
		{ 0,						0,		DepthBufferFormat::TYPE_UNKNOWN,		"default" },
		{ GL_DEPTH_COMPONENT16,		16,		DepthBufferFormat::TYPE_FIXED_POINT,	"fixed16" },
		{ GL_DEPTH_COMPONENT24,		24,		DepthBufferFormat::TYPE_FIXED_POINT,	"fixed24" },
		{ GL_DEPTH_COMPONENT32F,	32,		DepthBufferFormat::TYPE_FLOATING_POINT,	"float32" },
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthFormats); ++ndx)
	{
		const DepthBufferFormat& format = depthFormats[ndx];

		// enable works?
		addChild(new UsageTestCase(m_context, (std::string(format.name) + "_enable").c_str(), "test enable GL_POLYGON_OFFSET_FILL", format.internalFormat, format.name));

		// Really moves the polygons ?
		addChild(new UsageDisplacementTestCase(m_context, (std::string(format.name) + "_displacement_with_units").c_str(), "test polygon offset", format.internalFormat, format.name));

		// Really moves the polygons to right direction ?
		addChild(new UsagePositiveNegativeTestCase(m_context, (std::string(format.name) + "_render_with_units").c_str(), "test polygon offset", format.internalFormat, format.name));

		// Is total result clamped to [0,1] like promised?
		addChild(new ResultClampingTestCase(m_context, (std::string(format.name) + "_result_depth_clamp").c_str(), "test polygon offset clamping", format.internalFormat, format.name));

		// Slope really moves the polygon?
		addChild(new UsageSlopeTestCase(m_context, (std::string(format.name) + "_render_with_factor").c_str(), "test polygon offset factor", format.internalFormat, format.name));

		// Factor with zero slope
		addChild(new ZeroSlopeTestCase(m_context, (std::string(format.name) + "_factor_0_slope").c_str(), "test polygon offset factor", format.internalFormat, format.name));

		// Factor with 1.0 slope
		addChild(new OneSlopeTestCase(m_context, (std::string(format.name) + "_factor_1_slope").c_str(), "test polygon offset factor", format.internalFormat, format.name));
	}
}

} // Functional
} // gles3
} // deqp
