/*-------------------------------------------------------------------------
 * 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 Multisampling tests.
 *//*--------------------------------------------------------------------*/

#include "es3fMultisampleTests.hpp"
#include "gluStrUtil.hpp"
#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuSurface.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuCommandLine.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deString.h"

#include <string>
#include <vector>

#include "glw.h"

namespace deqp
{
namespace gles3
{
namespace Functional
{

using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::IVec4;
using tcu::TestLog;
using std::vector;

static const GLenum		FBO_COLOR_FORMAT	= GL_RGBA8;
static const float		SQRT_HALF			= 0.707107f;

namespace
{

struct QuadCorners
{
	Vec2 p0;
	Vec2 p1;
	Vec2 p2;
	Vec2 p3;

	QuadCorners(const Vec2& p0_, const Vec2& p1_, const Vec2& p2_, const Vec2& p3_) : p0(p0_), p1(p1_), p2(p2_), p3(p3_) {}
};

} // anonymous

static inline int getIterationCount (const tcu::TestContext& ctx, int defaultCount)
{
	int cmdLineValue = ctx.getCommandLine().getTestIterationCount();
	return cmdLineValue > 0 ? cmdLineValue : defaultCount;
}

static inline int getGLInteger (GLenum name)
{
	int result;
	GLU_CHECK_CALL(glGetIntegerv(name, &result));
	return result;
}

template<typename T>
static inline T min4 (T a, T b, T c, T d)
{
	return de::min(de::min(de::min(a, b), c), d);
}

template<typename T>
static inline T max4 (T a, T b, T c, T d)
{
	return de::max(de::max(de::max(a, b), c), d);
}

static inline bool isInsideQuad (const IVec2& point, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
{
	int dot0 = (point.x()-p0.x()) * (p1.y()-p0.y()) + (point.y()-p0.y()) * (p0.x()-p1.x());
	int dot1 = (point.x()-p1.x()) * (p2.y()-p1.y()) + (point.y()-p1.y()) * (p1.x()-p2.x());
	int dot2 = (point.x()-p2.x()) * (p3.y()-p2.y()) + (point.y()-p2.y()) * (p2.x()-p3.x());
	int dot3 = (point.x()-p3.x()) * (p0.y()-p3.y()) + (point.y()-p3.y()) * (p3.x()-p0.x());

	return (dot0 > 0) == (dot1 > 0) && (dot1 > 0) == (dot2 > 0) && (dot2 > 0) == (dot3 > 0);
}

/*--------------------------------------------------------------------*//*!
 * \brief Check if a region in an image is unicolored.
 *
 * Checks if the pixels in img inside the convex quadilateral defined by
 * p0, p1, p2 and p3 are all (approximately) of the same color.
 *//*--------------------------------------------------------------------*/
static bool isPixelRegionUnicolored (const tcu::Surface& img, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
{
	int			xMin				= de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMin				= de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	int			xMax				= de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMax				= de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	bool		insideEncountered	= false;	//!< Whether we have already seen at least one pixel inside the region.
	tcu::RGBA	insideColor;					//!< Color of the first pixel inside the region.

	for (int y = yMin; y <= yMax; y++)
	for (int x = xMin; x <= xMax; x++)
	{
		if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
		{
			tcu::RGBA pixColor = img.getPixel(x, y);

			if (insideEncountered)
			{
				if (!tcu::compareThreshold(pixColor, insideColor, tcu::RGBA(3, 3, 3, 3))) // Pixel color differs from already-detected color inside same region - region not unicolored.
					return false;
			}
			else
			{
				insideEncountered = true;
				insideColor = pixColor;
			}
		}
	}

	return true;
}

static bool drawUnicolorTestErrors (tcu::Surface& img, const tcu::PixelBufferAccess& errorImg, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
{
	int			xMin		= de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMin		= de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	int			xMax		= de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMax		= de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	tcu::RGBA	refColor	= img.getPixel((xMin + xMax) / 2, (yMin + yMax) / 2);

	for (int y = yMin; y <= yMax; y++)
	for (int x = xMin; x <= xMax; x++)
	{
		if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
		{
			if (!tcu::compareThreshold(img.getPixel(x, y), refColor, tcu::RGBA(3, 3, 3, 3)))
			{
				img.setPixel(x, y, tcu::RGBA::red);
				errorImg.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
			}
		}
	}

	return true;
}

/*--------------------------------------------------------------------*//*!
 * \brief Abstract base class handling common stuff for multisample cases.
 *//*--------------------------------------------------------------------*/
class MultisampleCase : public TestCase
{
public:
	struct FboParams
	{
		bool		useFbo;
		int			numSamples; //!< If 0, use implementation-defined maximum.
		bool		useDepth;
		bool		useStencil;

		FboParams (int numSamples_, bool useDepth_, bool useStencil_)
			: useFbo			(true)
			, numSamples		(numSamples_)
			, useDepth			(useDepth_)
			, useStencil		(useStencil_)
		{
		}

		FboParams (void)
			: useFbo			(false)
			, numSamples		(-1)
			, useDepth			(false)
			, useStencil		(false)
		{
		}
	};

						MultisampleCase			(Context& context, const char* name, const char* desc, int desiredViewportSize, const FboParams& fboParams = FboParams());
	virtual				~MultisampleCase		(void);

	virtual void		init					(void);
	virtual void		deinit					(void);

protected:
	void				renderTriangle			(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
	void				renderTriangle			(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const;
	void				renderTriangle			(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
	void				renderTriangle			(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const;
	void				renderQuad				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const;
	void				renderQuad				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const;
	void				renderLine				(const Vec2& p0, const Vec2& p1, const Vec4& color) const;

	void				randomizeViewport		(void);
	void				readImage				(tcu::Surface& dst) const;

	IVec2				getRenderTargetSize		(void) const 				{ return IVec2(m_renderWidth, m_renderHeight); }

	int					m_numSamples;

	int					m_viewportSize;

private:
						MultisampleCase			(const MultisampleCase& other);
	MultisampleCase&	operator=				(const MultisampleCase& other);

	const int			m_desiredViewportSize;

	const FboParams		m_fboParams;
	deUint32			m_msColorRbo;
	deUint32			m_msDepthStencilRbo;
	deUint32			m_resolveColorRbo;
	deUint32			m_msFbo;
	deUint32			m_resolveFbo;

	glu::ShaderProgram*	m_program;
	int					m_attrPositionLoc;
	int					m_attrColorLoc;

	int					m_renderWidth;
	int					m_renderHeight;
	int					m_viewportX;
	int					m_viewportY;
	de::Random			m_rnd;
};

MultisampleCase::MultisampleCase (Context& context, const char* name, const char* desc, int desiredViewportSize, const FboParams& fboParams)
	: TestCase				(context, name, desc)
	, m_numSamples			(0)
	, m_viewportSize		(0)
	, m_desiredViewportSize	(desiredViewportSize)
	, m_fboParams			(fboParams)
	, m_msColorRbo			(0)
	, m_msDepthStencilRbo	(0)
	, m_resolveColorRbo		(0)
	, m_msFbo				(0)
	, m_resolveFbo			(0)
	, m_program				(DE_NULL)
	, m_attrPositionLoc		(-1)
	, m_attrColorLoc		(-1)
	, m_renderWidth			(fboParams.useFbo ? 2*desiredViewportSize : context.getRenderTarget().getWidth())
	, m_renderHeight		(fboParams.useFbo ? 2*desiredViewportSize : context.getRenderTarget().getHeight())
	, m_viewportX			(0)
	, m_viewportY			(0)
	, m_rnd					(deStringHash(name))
{
	if (m_fboParams.useFbo)
		DE_ASSERT(m_fboParams.numSamples >= 0);
}

MultisampleCase::~MultisampleCase (void)
{
	MultisampleCase::deinit();
}

void MultisampleCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;

	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));

	if (m_msColorRbo != 0)
	{
		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_msColorRbo));
		m_msColorRbo = 0;
	}
	if (m_msDepthStencilRbo != 0)
	{
		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_msDepthStencilRbo));
		m_msDepthStencilRbo = 0;
	}
	if (m_resolveColorRbo != 0)
	{
		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_resolveColorRbo));
		m_resolveColorRbo = 0;
	}

	if (m_msFbo != 0)
	{
		GLU_CHECK_CALL(glDeleteFramebuffers(1, &m_msFbo));
		m_msFbo = 0;
	}
	if (m_resolveFbo != 0)
	{
		GLU_CHECK_CALL(glDeleteFramebuffers(1, &m_resolveFbo));
		m_resolveFbo = 0;
	}
}

void MultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
{
	float vertexPositions[] =
	{
		p0.x(), p0.y(), p0.z(), 1.0f,
		p1.x(), p1.y(), p1.z(), 1.0f,
		p2.x(), p2.y(), p2.z(), 1.0f
	};
	float vertexColors[] =
	{
		c0.x(), c0.y(), c0.z(), c0.w(),
		c1.x(), c1.y(), c1.z(), c1.w(),
		c2.x(), c2.y(), c2.z(), c2.w(),
	};

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));

	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
}

void MultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const
{
	renderTriangle(p0, p1, p2, color, color, color);
}

void MultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
{
	renderTriangle(Vec3(p0.x(), p0.y(), 0.0f),
				   Vec3(p1.x(), p1.y(), 0.0f),
				   Vec3(p2.x(), p2.y(), 0.0f),
				   c0, c1, c2);
}

void MultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const
{
	renderTriangle(p0, p1, p2, color, color, color);
}

void MultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const
{
	renderTriangle(p0, p1, p2, c0, c1, c2);
	renderTriangle(p2, p1, p3, c2, c1, c3);
}

void MultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const
{
	renderQuad(p0, p1, p2, p3, color, color, color, color);
}

void MultisampleCase::renderLine (const Vec2& p0, const Vec2& p1, const Vec4& color) const
{
	float vertexPositions[] =
	{
		p0.x(), p0.y(), 0.0f, 1.0f,
		p1.x(), p1.y(), 0.0f, 1.0f
	};
	float vertexColors[] =
	{
		color.x(), color.y(), color.z(), color.w(),
		color.x(), color.y(), color.z(), color.w()
	};

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));

	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
	GLU_CHECK_CALL(glDrawArrays(GL_LINES, 0, 2));
}

void MultisampleCase::randomizeViewport (void)
{
	m_viewportX = m_rnd.getInt(0, m_renderWidth - m_viewportSize);
	m_viewportY = m_rnd.getInt(0, m_renderHeight - m_viewportSize);

	GLU_CHECK_CALL(glViewport(m_viewportX, m_viewportY, m_viewportSize, m_viewportSize));
}

void MultisampleCase::readImage (tcu::Surface& dst) const
{
	if (m_fboParams.useFbo)
	{
		GLU_CHECK_CALL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFbo));
		GLU_CHECK_CALL(glBlitFramebuffer(0, 0, m_renderWidth, m_renderHeight, 0, 0, m_renderWidth, m_renderHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST));
		GLU_CHECK_CALL(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_resolveFbo));

		glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess());

		GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_msFbo));
	}
	else
		glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess());
}

void MultisampleCase::init (void)
{
	static const char* vertShaderSource =
		"#version 300 es\n"
		"in highp vec4 a_position;\n"
		"in mediump vec4 a_color;\n"
		"out mediump vec4 v_color;\n"
		"void main()\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"	v_color = a_color;\n"
		"}\n";

	static const char* fragShaderSource =
		"#version 300 es\n"
		"in mediump vec4 v_color;\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"void main()\n"
		"{\n"
		"	o_color = v_color;\n"
		"}\n";

	TestLog& log = m_testCtx.getLog();

	if (!m_fboParams.useFbo && m_context.getRenderTarget().getNumSamples() <= 1)
		throw tcu::NotSupportedError("No multisample buffers");

	if (m_fboParams.useFbo)
	{
		if (m_fboParams.numSamples > 0)
			m_numSamples = m_fboParams.numSamples;
		else
		{
			log << TestLog::Message << "Querying maximum number of samples for " << glu::getPixelFormatName(FBO_COLOR_FORMAT) << " with glGetInternalformativ()" << TestLog::EndMessage;
			GLU_CHECK_CALL(glGetInternalformativ(GL_RENDERBUFFER, FBO_COLOR_FORMAT, GL_SAMPLES, 1, &m_numSamples));
		}

		log << TestLog::Message << "Using FBO of size (" << m_renderWidth << ", " << m_renderHeight << ") with " << m_numSamples << " samples" << TestLog::EndMessage;
	}
	else
	{
		// Query and log number of samples per pixel.

		m_numSamples = getGLInteger(GL_SAMPLES);
		log << TestLog::Message << "GL_SAMPLES = " << m_numSamples << TestLog::EndMessage;
	}

	// Prepare program.

	DE_ASSERT(!m_program);

	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
	if (!m_program->isOk())
		throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__);

	GLU_CHECK_CALL(m_attrPositionLoc	= glGetAttribLocation(m_program->getProgram(), "a_position"));
	GLU_CHECK_CALL(m_attrColorLoc		= glGetAttribLocation(m_program->getProgram(), "a_color"));

	if (m_attrPositionLoc < 0 || m_attrColorLoc < 0)
	{
		delete m_program;
		throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__);
	}

	if (m_fboParams.useFbo)
	{
		DE_STATIC_ASSERT(sizeof(deUint32) == sizeof(GLuint));

		// Setup ms color RBO.
		GLU_CHECK_CALL(glGenRenderbuffers(1, &m_msColorRbo));
		GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_msColorRbo));

		// If glRenderbufferStorageMultisample() fails, check if it's because of a too high sample count.
		// \note We don't do the check until now because some implementations can't handle the GL_SAMPLES query with glGetInternalformativ(),
		//		 and we don't want that to be the cause of test case failure.
		try
		{
			GLU_CHECK_CALL(glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, FBO_COLOR_FORMAT, m_renderWidth, m_renderHeight));
		}
		catch (const glu::Error&)
		{
			GLint maxSampleCount = -1;
			GLU_CHECK_CALL(glGetInternalformativ(GL_RENDERBUFFER, FBO_COLOR_FORMAT, GL_SAMPLES, 1, &maxSampleCount));
			if (maxSampleCount < m_numSamples)
				throw tcu::NotSupportedError(std::string("") + "Maximum sample count returned by glGetInternalformativ() for " + glu::getPixelFormatName(FBO_COLOR_FORMAT) + " is only " + de::toString(maxSampleCount));
			else
				throw;
		}

		if (m_fboParams.useDepth || m_fboParams.useStencil)
		{
			// Setup ms depth & stencil RBO.
			GLU_CHECK_CALL(glGenRenderbuffers(1, &m_msDepthStencilRbo));
			GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_msDepthStencilRbo));
			GLU_CHECK_CALL(glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, GL_DEPTH24_STENCIL8, m_renderWidth, m_renderHeight));
		}

		// Setup ms FBO.
		GLU_CHECK_CALL(glGenFramebuffers(1, &m_msFbo));
		GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_msFbo));
		GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_msColorRbo));
		GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_msDepthStencilRbo));

		// Setup resolve color RBO.
		GLU_CHECK_CALL(glGenRenderbuffers(1, &m_resolveColorRbo));
		GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_resolveColorRbo));
		GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, FBO_COLOR_FORMAT, m_renderWidth, m_renderHeight));

		// Setup resolve FBO.
		GLU_CHECK_CALL(glGenFramebuffers(1, &m_resolveFbo));
		GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo));
		GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_resolveColorRbo));

		// Use ms FBO.
		GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_msFbo));
	}

	// Get suitable viewport size.

	m_viewportSize = de::min<int>(m_desiredViewportSize, de::min(m_renderWidth, m_renderHeight));
	randomizeViewport();
}

/*--------------------------------------------------------------------*//*!
 * \brief Base class for cases testing the value of sample count.
 *
 * Draws a test pattern (defined by renderPattern() of an inheriting class)
 * and counts the number of distinct colors in the resulting image. That
 * number should be at least the value of sample count plus one. This is
 * repeated with increased values of m_currentIteration until this correct
 * number of colors is detected or m_currentIteration reaches
 * m_maxNumIterations.
 *//*--------------------------------------------------------------------*/
class NumSamplesCase : public MultisampleCase
{
public:
						NumSamplesCase			(Context& context, const char* name, const char* description, const FboParams& fboParams = FboParams());
						~NumSamplesCase			(void) {}

	IterateResult		iterate					(void);

protected:
	virtual void		renderPattern			(void) const = 0;

	int					m_currentIteration;

private:
	enum { DEFAULT_MAX_NUM_ITERATIONS = 16 };

	const int			m_maxNumIterations;
	vector<tcu::RGBA>	m_detectedColors;
};

NumSamplesCase::NumSamplesCase (Context& context, const char* name, const char* description, const FboParams& fboParams)
	: MultisampleCase		(context, name, description, 256, fboParams)
	, m_currentIteration	(0)
	, m_maxNumIterations	(getIterationCount(m_testCtx, DEFAULT_MAX_NUM_ITERATIONS))
{
}

NumSamplesCase::IterateResult NumSamplesCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	renderPattern();

	// Read and log rendered image.

	readImage(renderedImg);

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	// Detect new, previously unseen colors from image.

	int requiredNumDistinctColors = m_numSamples + 1;

	for (int y = 0; y < renderedImg.getHeight() && (int)m_detectedColors.size() < requiredNumDistinctColors; y++)
	for (int x = 0; x < renderedImg.getWidth() && (int)m_detectedColors.size() < requiredNumDistinctColors; x++)
	{
		tcu::RGBA color = renderedImg.getPixel(x, y);

		int i;
		for (i = 0; i < (int)m_detectedColors.size(); i++)
		{
			if (tcu::compareThreshold(color, m_detectedColors[i], tcu::RGBA(3, 3, 3, 3)))
				break;
		}

		if (i == (int)m_detectedColors.size())
			m_detectedColors.push_back(color); // Color not previously detected.
	}

	// Log results.

	log << TestLog::Message
		<< "Number of distinct colors detected so far: "
		<< ((int)m_detectedColors.size() >= requiredNumDistinctColors ? "at least " : "")
		<< de::toString(m_detectedColors.size())
		<< TestLog::EndMessage;

	if ((int)m_detectedColors.size() < requiredNumDistinctColors)
	{
		// Haven't detected enough different colors yet.

		m_currentIteration++;

		if (m_currentIteration >= m_maxNumIterations)
		{
			const IVec2 targetSize 			= getRenderTargetSize();
			const int 	detectedNumSamples 	= (int)m_detectedColors.size() - 1; // One color is the background

			log << TestLog::Message << "Failure: Number of distinct colors detected is lower than sample count+1" << TestLog::EndMessage;

			// For high resolution render targets the lack of samples is not likely detected by a human
			// and for GLES 3.0 the application cannot observe the sample count directly. So, it only
			// warrants a quality warning.
			if ((targetSize.x() >= 2048 || targetSize.y() >= 2048) && (detectedNumSamples >= (m_numSamples/2)))
				m_context.getTestContext().setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Measured sample count below the advertised count");
			else
				m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
			return STOP;
		}
		else
		{
			log << TestLog::Message << "The number of distinct colors detected is lower than sample count+1 - trying again with a slightly altered pattern" << TestLog::EndMessage;
			return CONTINUE;
		}
	}
	else
	{
		log << TestLog::Message << "Success: The number of distinct colors detected is at least sample count+1" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
		return STOP;
	}
}

class PolygonNumSamplesCase : public NumSamplesCase
{
public:
			PolygonNumSamplesCase	(Context& context, const char* name, const char* description, int numFboSamples = 0);
			~PolygonNumSamplesCase	(void) {}

protected:
	void	renderPattern			(void) const;
};

PolygonNumSamplesCase::PolygonNumSamplesCase (Context& context, const char* name, const char* description, int numFboSamples)
	: NumSamplesCase(context, name, description, numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
{
}

void PolygonNumSamplesCase::renderPattern (void) const
{
	// The test pattern consists of several triangles with edges at different angles.

	const int numTriangles = 25;
	for (int i = 0; i < numTriangles; i++)
	{
		float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles + 0.001f*(float)m_currentIteration;
		float angle1 = 2.0f*DE_PI * (float)(i + 0.5f)	/ (float)numTriangles + 0.001f*(float)m_currentIteration;

		renderTriangle(Vec2(0.0f, 0.0f),
					   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
					   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
					   Vec4(1.0f));
	}
}

class LineNumSamplesCase : public NumSamplesCase
{
public:
			LineNumSamplesCase		(Context& context, const char* name, const char* description, int numFboSamples = 0);
			~LineNumSamplesCase		(void) {}

protected:
	void	renderPattern			(void) const;
};

LineNumSamplesCase::LineNumSamplesCase (Context& context, const char* name, const char* description, int numFboSamples)
	: NumSamplesCase (context, name, description, numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
{
}

void LineNumSamplesCase::renderPattern (void) const
{
	// The test pattern consists of several lines at different angles.

	// We scale the number of lines based on the viewport size. This is because a gl line's thickness is
	// constant in pixel units, i.e. they get relatively thicker as viewport size decreases. Thus we must
	// decrease the number of lines in order to decrease the extent of overlap among the lines in the
	// center of the pattern.
	const int numLines = (int)(100.0f * deFloatSqrt((float)m_viewportSize / 256.0f));

	for (int i = 0; i < numLines; i++)
	{
		float angle = 2.0f*DE_PI * (float)i / (float)numLines + 0.001f*(float)m_currentIteration;
		renderLine(Vec2(0.0f, 0.0f), Vec2(deFloatCos(angle)*0.95f, deFloatSin(angle)*0.95f), Vec4(1.0f));
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Case testing behaviour of common edges when multisampling.
 *
 * Draws a number of test patterns, each with a number of quads, each made
 * of two triangles, rotated at different angles. The inner edge inside the
 * quad (i.e. the common edge of the two triangles) still should not be
 * visible, despite multisampling - i.e. the two triangles forming the quad
 * should never get any common coverage bits in any pixel.
 *//*--------------------------------------------------------------------*/
class CommonEdgeCase : public MultisampleCase
{
public:
	enum CaseType
	{
		CASETYPE_SMALL_QUADS = 0,				//!< Draw several small quads per iteration.
		CASETYPE_BIGGER_THAN_VIEWPORT_QUAD,		//!< Draw one bigger-than-viewport quad per iteration.
		CASETYPE_FIT_VIEWPORT_QUAD,				//!< Draw one exactly viewport-sized, axis aligned quad per iteration.

		CASETYPE_LAST
	};

					CommonEdgeCase			(Context& context, const char* name, const char* description, CaseType caseType, int numFboSamples = 0);
					~CommonEdgeCase			(void) {}

	void			init					(void);

	IterateResult	iterate					(void);

private:
	enum
	{
		DEFAULT_SMALL_QUADS_ITERATIONS					= 16,
		DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS	= 8*8
		// \note With CASETYPE_FIT_VIEWPORT_QUAD, we don't do rotations other than multiples of 90 deg -> constant number of iterations.
	};

	const CaseType	m_caseType;

	const int		m_numIterations;
	int				m_currentIteration;
};

CommonEdgeCase::CommonEdgeCase (Context& context, const char* name, const char* description, CaseType caseType, int numFboSamples)
	: MultisampleCase		(context, name, description, caseType == CASETYPE_SMALL_QUADS ? 128 : 32, numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
	, m_caseType			(caseType)
	, m_numIterations		(caseType == CASETYPE_SMALL_QUADS					? getIterationCount(m_testCtx, DEFAULT_SMALL_QUADS_ITERATIONS)
							: caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD	? getIterationCount(m_testCtx, DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS)
							: 8)
	, m_currentIteration	(0)
{
}

void CommonEdgeCase::init (void)
{
	MultisampleCase::init();

	if (m_caseType == CASETYPE_SMALL_QUADS)
	{
		// Check for a big enough viewport. With too small viewports the test case can't analyze the resulting image well enough.

		const int minViewportSize = 32;

		if (m_viewportSize < minViewportSize)
			throw tcu::InternalError("Render target width or height too low (is " + de::toString(m_viewportSize) + ", should be at least " + de::toString(minViewportSize) + ")");
	}

	GLU_CHECK_CALL(glEnable(GL_BLEND));
	GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
	GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));
	m_testCtx.getLog() << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage;
}

CommonEdgeCase::IterateResult CommonEdgeCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
	tcu::Surface	errorImg		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	// Draw test pattern. Test patterns consist of quads formed with two triangles.
	// After drawing the pattern, we check that the interior pixels of each quad are
	// all the same color - this is meant to verify that there are no artifacts on the inner edge.

	vector<QuadCorners> unicoloredRegions;

	if (m_caseType == CASETYPE_SMALL_QUADS)
	{
		// Draw several quads, rotated at different angles.

		const float		quadDiagLen = 2.0f / 3.0f * 0.9f; // \note Fit 3 quads in both x and y directions.
		float			angleCos;
		float			angleSin;

		// \note First and second iteration get exact 0 (and 90, 180, 270) and 45 (and 135, 225, 315) angle quads, as they are kind of a special case.

		if (m_currentIteration == 0)
		{
			angleCos = 1.0f;
			angleSin = 0.0f;
		}
		else if (m_currentIteration == 1)
		{
			angleCos = SQRT_HALF;
			angleSin = SQRT_HALF;
		}
		else
		{
			float angle = 0.5f * DE_PI * (float)(m_currentIteration-1) / (float)(m_numIterations-1);
			angleCos = deFloatCos(angle);
			angleSin = deFloatSin(angle);
		}

		Vec2 corners[4] =
		{
			0.5f * quadDiagLen * Vec2( angleCos,  angleSin),
			0.5f * quadDiagLen * Vec2(-angleSin,  angleCos),
			0.5f * quadDiagLen * Vec2(-angleCos, -angleSin),
			0.5f * quadDiagLen * Vec2( angleSin, -angleCos)
		};

		unicoloredRegions.reserve(8);

		// Draw 8 quads.
		// First four are rotated at angles angle+0, angle+90, angle+180 and angle+270.
		// Last four are rotated the same angles as the first four, but the ordering of the last triangle's vertices is reversed.

		for (int quadNdx = 0; quadNdx < 8; quadNdx++)
		{
			Vec2 center = (2.0f-quadDiagLen) * Vec2((float)(quadNdx%3), (float)(quadNdx/3)) / 2.0f - 0.5f*(2.0f-quadDiagLen);

			renderTriangle(corners[(0+quadNdx) % 4] + center,
						   corners[(1+quadNdx) % 4] + center,
						   corners[(2+quadNdx) % 4] + center,
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));

			if (quadNdx >= 4)
			{
				renderTriangle(corners[(3+quadNdx) % 4] + center,
							   corners[(2+quadNdx) % 4] + center,
							   corners[(0+quadNdx) % 4] + center,
							   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
			}
			else
			{
				renderTriangle(corners[(0+quadNdx) % 4] + center,
							   corners[(2+quadNdx) % 4] + center,
							   corners[(3+quadNdx) % 4] + center,
							   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
			}

			// The size of the "interior" of a quad is assumed to be approximately unicolorRegionScale*<actual size of quad>.
			// By "interior" we here mean the region of non-boundary pixels of the rendered quad for which we can safely assume
			// that it has all coverage bits set to 1, for every pixel.
			float unicolorRegionScale = 1.0f - 6.0f*2.0f / (float)m_viewportSize / quadDiagLen;
			unicoloredRegions.push_back(QuadCorners((center + corners[0]*unicolorRegionScale),
													(center + corners[1]*unicolorRegionScale),
													(center + corners[2]*unicolorRegionScale),
													(center + corners[3]*unicolorRegionScale)));
		}
	}
	else if (m_caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD)
	{
		// Draw a bigger-than-viewport quad, rotated at an angle depending on m_currentIteration.

		int				quadBaseAngleNdx		= m_currentIteration / 8;
		int				quadSubAngleNdx			= m_currentIteration % 8;
		float			angleCos;
		float			angleSin;

		if (quadBaseAngleNdx == 0)
		{
			angleCos = 1.0f;
			angleSin = 0.0f;
		}
		else if (quadBaseAngleNdx == 1)
		{
			angleCos = SQRT_HALF;
			angleSin = SQRT_HALF;
		}
		else
		{
			float angle = 0.5f * DE_PI * (float)(m_currentIteration-1) / (float)(m_numIterations-1);
			angleCos = deFloatCos(angle);
			angleSin = deFloatSin(angle);
		}

		float quadDiagLen = 2.5f / de::max(angleCos, angleSin);

		Vec2 corners[4] =
		{
			0.5f * quadDiagLen * Vec2( angleCos,  angleSin),
			0.5f * quadDiagLen * Vec2(-angleSin,  angleCos),
			0.5f * quadDiagLen * Vec2(-angleCos, -angleSin),
			0.5f * quadDiagLen * Vec2( angleSin, -angleCos)
		};

		renderTriangle(corners[(0+quadSubAngleNdx) % 4],
					   corners[(1+quadSubAngleNdx) % 4],
					   corners[(2+quadSubAngleNdx) % 4],
					   Vec4(0.5f, 0.5f, 0.5f, 1.0f));

		if (quadSubAngleNdx >= 4)
		{
			renderTriangle(corners[(3+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(0+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}
		else
		{
			renderTriangle(corners[(0+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(3+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}

		float unicolorRegionScale = 1.0f - 6.0f*2.0f / (float)m_viewportSize / quadDiagLen;
		unicoloredRegions.push_back(QuadCorners((corners[0]*unicolorRegionScale),
												(corners[1]*unicolorRegionScale),
												(corners[2]*unicolorRegionScale),
												(corners[3]*unicolorRegionScale)));
	}
	else if (m_caseType == CASETYPE_FIT_VIEWPORT_QUAD)
	{
		// Draw an exactly viewport-sized quad, rotated by multiples of 90 degrees angle depending on m_currentIteration.

		int quadSubAngleNdx = m_currentIteration % 8;

		Vec2 corners[4] =
		{
			Vec2( 1.0f,  1.0f),
			Vec2(-1.0f,  1.0f),
			Vec2(-1.0f, -1.0f),
			Vec2( 1.0f, -1.0f)
		};

		renderTriangle(corners[(0+quadSubAngleNdx) % 4],
					   corners[(1+quadSubAngleNdx) % 4],
					   corners[(2+quadSubAngleNdx) % 4],
					   Vec4(0.5f, 0.5f, 0.5f, 1.0f));

		if (quadSubAngleNdx >= 4)
		{
			renderTriangle(corners[(3+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(0+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}
		else
		{
			renderTriangle(corners[(0+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(3+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}

		unicoloredRegions.push_back(QuadCorners(corners[0], corners[1], corners[2], corners[3]));
	}
	else
		DE_ASSERT(false);

	// Read pixels and check unicolored regions.

	readImage(renderedImg);

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

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	bool errorsDetected = false;
	for (int i = 0; i < (int)unicoloredRegions.size(); i++)
	{
		const QuadCorners&	region					= unicoloredRegions[i];
		IVec2				p0Win					= ((region.p0+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		IVec2				p1Win					= ((region.p1+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		IVec2				p2Win					= ((region.p2+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		IVec2				p3Win					= ((region.p3+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		bool				errorsInCurrentRegion	= !isPixelRegionUnicolored(renderedImg, p0Win, p1Win, p2Win, p3Win);

		if (errorsInCurrentRegion)
			drawUnicolorTestErrors(renderedImg, errorImg.getAccess(), p0Win, p1Win, p2Win, p3Win);

		errorsDetected = errorsDetected || errorsInCurrentRegion;
	}

	m_currentIteration++;

	if (errorsDetected)
	{
		log << TestLog::Message << "Failure: Not all quad interiors seem unicolored - common-edge artifacts?" << TestLog::EndMessage;
		log << TestLog::Message << "Erroneous pixels are drawn red in the following image" << TestLog::EndMessage;
		log << TestLog::Image("RenderedImageWithErrors",	"Rendered image with errors marked",	renderedImg,	QP_IMAGE_COMPRESSION_MODE_PNG);
		log << TestLog::Image("ErrorsOnly",					"Image with error pixels only",			errorImg,		QP_IMAGE_COMPRESSION_MODE_PNG);
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}
	else if (m_currentIteration < m_numIterations)
	{
		log << TestLog::Message << "Quads seem OK - moving on to next pattern" << TestLog::EndMessage;
		return CONTINUE;
	}
	else
	{
		log << TestLog::Message << "Success: All quad interiors seem unicolored (no common-edge artifacts)" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
		return STOP;
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Test that depth values are per-sample.
 *
 * Draws intersecting, differently-colored polygons and checks that there
 * are at least sample count+1 distinct colors present, due to some of the
 * samples at the intersection line belonging to one and some to another
 * polygon.
 *//*--------------------------------------------------------------------*/
class SampleDepthCase : public NumSamplesCase
{
public:
						SampleDepthCase			(Context& context, const char* name, const char* description, int numFboSamples = 0);
						~SampleDepthCase		(void) {}

	void				init					(void);

protected:
	void				renderPattern			(void) const;
};

SampleDepthCase::SampleDepthCase (Context& context, const char* name, const char* description, int numFboSamples)
	: NumSamplesCase (context, name, description, numFboSamples >= 0 ? FboParams(numFboSamples, true, false) : FboParams())
{
}

void SampleDepthCase::init (void)
{
	TestLog& log = m_testCtx.getLog();

	if (m_context.getRenderTarget().getDepthBits() == 0)
		TCU_THROW(NotSupportedError, "Test requires depth buffer");

	MultisampleCase::init();

	GLU_CHECK_CALL(glEnable(GL_DEPTH_TEST));
	GLU_CHECK_CALL(glDepthFunc(GL_LESS));

	log << TestLog::Message << "Depth test enabled, depth func is GL_LESS" << TestLog::EndMessage;
	log << TestLog::Message << "Drawing several bigger-than-viewport black or white polygons intersecting each other" << TestLog::EndMessage;
}

void SampleDepthCase::renderPattern (void) const
{
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
	GLU_CHECK_CALL(glClearDepthf(1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

	{
		const int numPolygons = 50;

		for (int i = 0; i < numPolygons; i++)
		{
			Vec4	color	= i % 2 == 0 ? Vec4(1.0f, 1.0f, 1.0f, 1.0f) : Vec4(0.0f, 0.0f, 0.0f, 1.0f);
			float	angle	= 2.0f * DE_PI * (float)i / (float)numPolygons + 0.001f*(float)m_currentIteration;
			Vec3	pt0		(3.0f*deFloatCos(angle + 2.0f*DE_PI*0.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*0.0f/3.0f), 1.0f);
			Vec3	pt1		(3.0f*deFloatCos(angle + 2.0f*DE_PI*1.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*1.0f/3.0f), 0.0f);
			Vec3	pt2		(3.0f*deFloatCos(angle + 2.0f*DE_PI*2.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*2.0f/3.0f), 0.0f);

			renderTriangle(pt0, pt1, pt2, color);
		}
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Test that stencil buffer values are per-sample.
 *
 * Draws a unicolored pattern and marks drawn samples in stencil buffer;
 * then clears and draws a viewport-size quad with that color and with
 * proper stencil test such that the resulting image should be exactly the
 * same as after the pattern was first drawn.
 *//*--------------------------------------------------------------------*/
class SampleStencilCase : public MultisampleCase
{
public:
						SampleStencilCase		(Context& context, const char* name, const char* description, int numFboSamples = 0);
						~SampleStencilCase		(void) {}

	void				init					(void);
	IterateResult		iterate					(void);
};

SampleStencilCase::SampleStencilCase (Context& context, const char* name, const char* description, int numFboSamples)
	: MultisampleCase (context, name, description, 256, numFboSamples >= 0 ? FboParams(numFboSamples, false, true) : FboParams())
{
}

void SampleStencilCase::init (void)
{
	if (m_context.getRenderTarget().getStencilBits() == 0)
		TCU_THROW(NotSupportedError, "Test requires stencil buffer");

	MultisampleCase::init();
}

SampleStencilCase::IterateResult SampleStencilCase::iterate (void)
{
	TestLog&		log					= m_testCtx.getLog();
	tcu::Surface	renderedImgFirst	(m_viewportSize, m_viewportSize);
	tcu::Surface	renderedImgSecond	(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClearStencil(0));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
	GLU_CHECK_CALL(glEnable(GL_STENCIL_TEST));
	GLU_CHECK_CALL(glStencilFunc(GL_ALWAYS, 1, 1));
	GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE));

	log << TestLog::Message << "Drawing a pattern with glStencilFunc(GL_ALWAYS, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)" << TestLog::EndMessage;

	{
		const int numTriangles = 25;
		for (int i = 0; i < numTriangles; i++)
		{
			float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles;
			float angle1 = 2.0f*DE_PI * (float)(i + 0.5f)	/ (float)numTriangles;

			renderTriangle(Vec2(0.0f, 0.0f),
						   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
						   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
						   Vec4(1.0f));
		}
	}

	readImage(renderedImgFirst);
	log << TestLog::Image("RenderedImgFirst", "First image rendered", renderedImgFirst, QP_IMAGE_COMPRESSION_MODE_PNG);

	log << TestLog::Message << "Clearing color buffer to black" << TestLog::EndMessage;

	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
	GLU_CHECK_CALL(glStencilFunc(GL_EQUAL, 1, 1));
	GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP));

	{
		log << TestLog::Message << "Checking that color buffer was actually cleared to black" << TestLog::EndMessage;

		tcu::Surface clearedImg(m_viewportSize, m_viewportSize);
		readImage(clearedImg);

		for (int y = 0; y < clearedImg.getHeight(); y++)
		for (int x = 0; x < clearedImg.getWidth(); x++)
		{
			const tcu::RGBA& clr = clearedImg.getPixel(x, y);
			if (clr != tcu::RGBA::black)
			{
				log << TestLog::Message << "Failure: first non-black pixel, color " << clr << ", detected at coordinates (" << x << ", " << y << ")" << TestLog::EndMessage;
				log << TestLog::Image("ClearedImg", "Image after clearing, erroneously non-black", clearedImg);
				m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
				return STOP;
			}
		}
	}

	log << TestLog::Message << "Drawing a viewport-sized quad with glStencilFunc(GL_EQUAL, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) - should result in same image as the first" << TestLog::EndMessage;

	renderQuad(Vec2(-1.0f, -1.0f),
			   Vec2( 1.0f, -1.0f),
			   Vec2(-1.0f,  1.0f),
			   Vec2( 1.0f,  1.0f),
			   Vec4(1.0f));

	readImage(renderedImgSecond);
	log << TestLog::Image("RenderedImgSecond", "Second image rendered", renderedImgSecond, QP_IMAGE_COMPRESSION_MODE_PNG);

	bool passed = tcu::pixelThresholdCompare(log,
											 "ImageCompare",
											 "Image comparison",
											 renderedImgFirst,
											 renderedImgSecond,
											 tcu::RGBA(0),
											 tcu::COMPARE_LOG_ON_ERROR);

	if (passed)
		log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;

	m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
											 passed ? "Passed"				: "Failed");

	return STOP;
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests coverage mask generation proportionality property.
 *
 * Tests that the number of coverage bits in a coverage mask created by
 * GL_SAMPLE_ALPHA_TO_COVERAGE or GL_SAMPLE_COVERAGE is, on average,
 * proportional to the alpha or coverage value, respectively. Draws
 * multiple frames, each time increasing the alpha or coverage value used,
 * and checks that the average color is changing appropriately.
 *//*--------------------------------------------------------------------*/
class MaskProportionalityCase : public MultisampleCase
{
public:
	enum CaseType
	{
		CASETYPE_ALPHA_TO_COVERAGE = 0,
		CASETYPE_SAMPLE_COVERAGE,
		CASETYPE_SAMPLE_COVERAGE_INVERTED,

		CASETYPE_LAST
	};

					MaskProportionalityCase				(Context& context, const char* name, const char* description, CaseType type, int numFboSamples = 0);
					~MaskProportionalityCase			(void) {}

	void			init								(void);

	IterateResult	iterate								(void);

private:
	const CaseType	m_type;

	int				m_numIterations;
	int				m_currentIteration;

	deInt32			m_previousIterationColorSum;
};

MaskProportionalityCase::MaskProportionalityCase (Context& context, const char* name, const char* description, CaseType type, int numFboSamples)
	: MultisampleCase				(context, name, description, 32, numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
	, m_type						(type)
	, m_currentIteration			(0)
	, m_previousIterationColorSum	(-1)
{
}

void MaskProportionalityCase::init (void)
{
	TestLog& log = m_testCtx.getLog();

	MultisampleCase::init();

	if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
	{
		GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
		log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
	}
	else
	{
		DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);

		GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
		log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
	}

	m_numIterations = de::max(2, getIterationCount(m_testCtx, m_numSamples * 5));

	randomizeViewport(); // \note Using the same viewport for every iteration since coverage mask may depend on window-relative pixel coordinate.
}

MaskProportionalityCase::IterateResult MaskProportionalityCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
	deInt32			numPixels		= (deInt32)renderedImg.getWidth()*(deInt32)renderedImg.getHeight();

	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
	GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
	{
		GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
		log << TestLog::Message << "Using color mask TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
	}

	// Draw quad.

	{
		const Vec2		pt0						(-1.0f, -1.0f);
		const Vec2		pt1						( 1.0f, -1.0f);
		const Vec2		pt2						(-1.0f,  1.0f);
		const Vec2		pt3						( 1.0f,  1.0f);
		Vec4			quadColor				(1.0f, 0.0f, 0.0f, 1.0f);
		float			alphaOrCoverageValue	= (float)m_currentIteration / (float)(m_numIterations-1);

		if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
		{
			log << TestLog::Message << "Drawing a red quad using alpha value " + de::floatToString(alphaOrCoverageValue, 2) << TestLog::EndMessage;
			quadColor.w() = alphaOrCoverageValue;
		}
		else
		{
			DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);

			bool	isInverted		= m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED;
			float	coverageValue	= isInverted ? 1.0f - alphaOrCoverageValue : alphaOrCoverageValue;
			log << TestLog::Message << "Drawing a red quad using sample coverage value " + de::floatToString(coverageValue, 2) << (isInverted ? " (inverted)" : "") << TestLog::EndMessage;
			GLU_CHECK_CALL(glSampleCoverage(coverageValue, isInverted ? GL_TRUE : GL_FALSE));
		}

		renderQuad(pt0, pt1, pt2, pt3, quadColor);
	}

	// Read ang log image.

	readImage(renderedImg);

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	// Compute average red component in rendered image.

	deInt32 sumRed = 0;

	for (int y = 0; y < renderedImg.getHeight(); y++)
	for (int x = 0; x < renderedImg.getWidth(); x++)
		sumRed += renderedImg.getPixel(x, y).getRed();

	log << TestLog::Message << "Average red color component: " << de::floatToString((float)sumRed / 255.0f / (float)numPixels, 2) << TestLog::EndMessage;

	// Check if average color has decreased from previous frame's color.

	if (sumRed < m_previousIterationColorSum)
	{
		log << TestLog::Message << "Failure: Current average red color component is lower than previous" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}

	// Check if coverage mask is not all-zeros if alpha or coverage value is 0 (or 1, if inverted).

	if (m_currentIteration == 0 && sumRed != 0)
	{
		log << TestLog::Message << "Failure: Image should be completely black" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}

	if (m_currentIteration == m_numIterations-1 && sumRed != 0xff*numPixels)
	{
		log << TestLog::Message << "Failure: Image should be completely red" << TestLog::EndMessage;

		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}

	m_previousIterationColorSum = sumRed;

	m_currentIteration++;

	if (m_currentIteration >= m_numIterations)
	{
		log << TestLog::Message
			<< "Success: Number of coverage mask bits set appears to be, on average, proportional to "
			<< (m_type == CASETYPE_ALPHA_TO_COVERAGE ? "alpha" : m_type == CASETYPE_SAMPLE_COVERAGE ? "sample coverage value" : "inverted sample coverage value")
			<< TestLog::EndMessage;

		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
		return STOP;
	}
	else
		return CONTINUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests coverage mask generation constancy property.
 *
 * Tests that the coverage mask created by GL_SAMPLE_ALPHA_TO_COVERAGE or
 * GL_SAMPLE_COVERAGE is constant at given pixel coordinates, with a given
 * alpha component or coverage value, respectively. Draws two quads, with
 * the second one fully overlapping the first one such that at any given
 * pixel, both quads have the same alpha or coverage value. This way, if
 * the constancy property is fulfilled, only the second quad should be
 * visible.
 *//*--------------------------------------------------------------------*/
class MaskConstancyCase : public MultisampleCase
{
public:
	enum CaseType
	{
		CASETYPE_ALPHA_TO_COVERAGE = 0,		//!< Use only alpha-to-coverage.
		CASETYPE_SAMPLE_COVERAGE,			//!< Use only sample coverage.
		CASETYPE_SAMPLE_COVERAGE_INVERTED,	//!< Use only inverted sample coverage.
		CASETYPE_BOTH,						//!< Use both alpha-to-coverage and sample coverage.
		CASETYPE_BOTH_INVERTED,				//!< Use both alpha-to-coverage and inverted sample coverage.

		CASETYPE_LAST
	};

					MaskConstancyCase			(Context& context, const char* name, const char* description, CaseType type, int numFboSamples = 0);
					~MaskConstancyCase			(void) {}

	IterateResult	iterate						(void);

private:
	const bool		m_isAlphaToCoverageCase;
	const bool		m_isSampleCoverageCase;
	const bool		m_isInvertedSampleCoverageCase;
};

MaskConstancyCase::MaskConstancyCase (Context& context, const char* name, const char* description, CaseType type, int numFboSamples)
	: MultisampleCase					(context, name, description, 256, numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
	, m_isAlphaToCoverageCase			(type == CASETYPE_ALPHA_TO_COVERAGE			|| type == CASETYPE_BOTH						|| type == CASETYPE_BOTH_INVERTED)
	, m_isSampleCoverageCase			(type == CASETYPE_SAMPLE_COVERAGE			|| type == CASETYPE_SAMPLE_COVERAGE_INVERTED	|| type == CASETYPE_BOTH			|| type == CASETYPE_BOTH_INVERTED)
	, m_isInvertedSampleCoverageCase	(type == CASETYPE_SAMPLE_COVERAGE_INVERTED	|| type == CASETYPE_BOTH_INVERTED)
{
}

MaskConstancyCase::IterateResult MaskConstancyCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	if (m_isAlphaToCoverageCase)
	{
		GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
		GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
		log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
		log << TestLog::Message << "Color mask is TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
	}

	if (m_isSampleCoverageCase)
	{
		GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
		log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
	}

	log << TestLog::Message
		<< "Drawing several green quads, each fully overlapped by a red quad with the same "
		<< (m_isAlphaToCoverageCase ? "alpha" : "")
		<< (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
		<< (m_isInvertedSampleCoverageCase ? "inverted " : "")
		<< (m_isSampleCoverageCase ? "sample coverage" : "")
		<< " values"
		<< TestLog::EndMessage;

	const int numQuadRowsCols = m_numSamples*4;

	for (int row = 0; row < numQuadRowsCols; row++)
	{
		for (int col = 0; col < numQuadRowsCols; col++)
		{
			float		x0			= (float)(col+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
			float		x1			= (float)(col+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
			float		y0			= (float)(row+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
			float		y1			= (float)(row+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
			const Vec4	baseGreen	(0.0f, 1.0f, 0.0f, 0.0f);
			const Vec4	baseRed		(1.0f, 0.0f, 0.0f, 0.0f);
			Vec4		alpha0		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)col / (float)(numQuadRowsCols-1) : 1.0f);
			Vec4		alpha1		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)row / (float)(numQuadRowsCols-1) : 1.0f);

			if (m_isSampleCoverageCase)
			{
				float value = (float)(row*numQuadRowsCols + col) / (float)(numQuadRowsCols*numQuadRowsCols-1);
				GLU_CHECK_CALL(glSampleCoverage(m_isInvertedSampleCoverageCase ? 1.0f - value : value, m_isInvertedSampleCoverageCase ? GL_TRUE : GL_FALSE));
			}

			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen + alpha0,	baseGreen + alpha1,	baseGreen + alpha0,	baseGreen + alpha1);
			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed + alpha0,	baseRed + alpha1,	baseRed + alpha0,	baseRed + alpha1);
		}
	}

	readImage(renderedImg);

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	for (int y = 0; y < renderedImg.getHeight(); y++)
	for (int x = 0; x < renderedImg.getWidth(); x++)
	{
		if (renderedImg.getPixel(x, y).getGreen() > 0)
		{
			log << TestLog::Message << "Failure: Non-zero green color component detected - should have been completely overwritten by red quad" << TestLog::EndMessage;
			m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
			return STOP;
		}
	}

	log << TestLog::Message
		<< "Success: Coverage mask appears to be constant at a given pixel coordinate with a given "
		<< (m_isAlphaToCoverageCase ? "alpha" : "")
		<< (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
		<< (m_isSampleCoverageCase ? "coverage value" : "")
		<< TestLog::EndMessage;

	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");

	return STOP;
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests coverage mask inversion validity.
 *
 * Tests that the coverage masks obtained by glSampleCoverage(..., GL_TRUE)
 * and glSampleCoverage(..., GL_FALSE) are indeed each others' inverses.
 * This is done by drawing a pattern, with varying coverage values,
 * overlapped by a pattern that has inverted masks and is otherwise
 * identical. The resulting image is compared to one obtained by drawing
 * the same pattern but with all-ones coverage masks.
 *//*--------------------------------------------------------------------*/
class CoverageMaskInvertCase : public MultisampleCase
{
public:
					CoverageMaskInvertCase		(Context& context, const char* name, const char* description, int numFboSamples = 0);
					~CoverageMaskInvertCase		(void) {}

	IterateResult	iterate						(void);

private:
	void			drawPattern					(bool invertSampleCoverage) const;
};

CoverageMaskInvertCase::CoverageMaskInvertCase (Context& context, const char* name, const char* description, int numFboSamples)
	: MultisampleCase (context, name, description, 256, numFboSamples >= 0 ? FboParams(numFboSamples, false, false) : FboParams())
{
}

void CoverageMaskInvertCase::drawPattern (bool invertSampleCoverage) const
{
	const int numTriangles = 25;
	for (int i = 0; i < numTriangles; i++)
	{
		GLU_CHECK_CALL(glSampleCoverage((float)i / (float)(numTriangles-1), invertSampleCoverage ? GL_TRUE : GL_FALSE));

		float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles;
		float angle1 = 2.0f*DE_PI * (float)(i + 0.5f)	/ (float)numTriangles;

		renderTriangle(Vec2(0.0f, 0.0f),
					   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
					   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
					   Vec4(0.4f + (float)i/(float)numTriangles*0.6f,
							0.5f + (float)i/(float)numTriangles*0.3f,
							0.6f - (float)i/(float)numTriangles*0.5f,
							0.7f - (float)i/(float)numTriangles*0.7f));
	}
}

CoverageMaskInvertCase::IterateResult CoverageMaskInvertCase::iterate (void)
{
	TestLog&		log								= m_testCtx.getLog();
	tcu::Surface	renderedImgNoSampleCoverage		(m_viewportSize, m_viewportSize);
	tcu::Surface	renderedImgSampleCoverage		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glEnable(GL_BLEND));
	GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
	GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));
	log << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage;

	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE disabled" << TestLog::EndMessage;
	drawPattern(false);
	readImage(renderedImgNoSampleCoverage);

	log << TestLog::Image("RenderedImageNoSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE disabled", renderedImgNoSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);

	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
	GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using non-inverted masks" << TestLog::EndMessage;
	drawPattern(false);
	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using same sample coverage values but inverted masks" << TestLog::EndMessage;
	drawPattern(true);
	readImage(renderedImgSampleCoverage);

	log << TestLog::Image("RenderedImageSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE enabled", renderedImgSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);

	bool passed = tcu::pixelThresholdCompare(log,
											 "CoverageVsNoCoverage",
											 "Comparison of same pattern with GL_SAMPLE_COVERAGE disabled and enabled",
											 renderedImgNoSampleCoverage,
											 renderedImgSampleCoverage,
											 tcu::RGBA(0),
											 tcu::COMPARE_LOG_ON_ERROR);

	if (passed)
		log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;

	m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
											 passed ? "Passed"				: "Failed");

	return STOP;
}

MultisampleTests::MultisampleTests (Context& context)
	: TestCaseGroup(context, "multisample", "Multisampling tests")
{
}

MultisampleTests::~MultisampleTests (void)
{
}

void MultisampleTests::init (void)
{
	enum CaseType
	{
		CASETYPE_DEFAULT_FRAMEBUFFER = 0,
		CASETYPE_FBO_4_SAMPLES,
		CASETYPE_FBO_8_SAMPLES,
		CASETYPE_FBO_MAX_SAMPLES,

		CASETYPE_LAST
	};

	for (int caseTypeI = 0; caseTypeI < (int)CASETYPE_LAST; caseTypeI++)
	{
		CaseType		caseType		= (CaseType)caseTypeI;
		int				numFboSamples	= caseType == CASETYPE_DEFAULT_FRAMEBUFFER	? -1
										: caseType == CASETYPE_FBO_4_SAMPLES		? 4
										: caseType == CASETYPE_FBO_8_SAMPLES		? 8
										: caseType == CASETYPE_FBO_MAX_SAMPLES		? 0
										: -2;

		TestCaseGroup*	group			= new TestCaseGroup(m_context,
															caseType == CASETYPE_DEFAULT_FRAMEBUFFER	? "default_framebuffer" :
															caseType == CASETYPE_FBO_4_SAMPLES			? "fbo_4_samples" :
															caseType == CASETYPE_FBO_8_SAMPLES			? "fbo_8_samples" :
															caseType == CASETYPE_FBO_MAX_SAMPLES		? "fbo_max_samples" :
															DE_NULL,
															caseType == CASETYPE_DEFAULT_FRAMEBUFFER	? "Render into default framebuffer" :
															caseType == CASETYPE_FBO_4_SAMPLES			? "Render into a framebuffer object with 4 samples" :
															caseType == CASETYPE_FBO_8_SAMPLES			? "Render into a framebuffer object with 8 samples" :
															caseType == CASETYPE_FBO_MAX_SAMPLES		? "Render into a framebuffer object with the maximum number of samples" :
															DE_NULL);
		DE_ASSERT(group->getName() != DE_NULL);
		DE_ASSERT(group->getDescription() != DE_NULL);
		DE_ASSERT(numFboSamples >= -1);
		addChild(group);

		group->addChild(new PolygonNumSamplesCase		(m_context, "num_samples_polygon",			"Test sanity of the sample count, with polygons",										numFboSamples));
		group->addChild(new LineNumSamplesCase			(m_context, "num_samples_line",				"Test sanity of the sample count, with lines",											numFboSamples));
		group->addChild(new CommonEdgeCase				(m_context, "common_edge_small_quads",		"Test polygons' common edges with small quads",											CommonEdgeCase::CASETYPE_SMALL_QUADS,				numFboSamples));
		group->addChild(new CommonEdgeCase				(m_context, "common_edge_big_quad",			"Test polygons' common edges with bigger-than-viewport quads",							CommonEdgeCase::CASETYPE_BIGGER_THAN_VIEWPORT_QUAD,	numFboSamples));
		group->addChild(new CommonEdgeCase				(m_context, "common_edge_viewport_quad",	"Test polygons' common edges with exactly viewport-sized quads",						CommonEdgeCase::CASETYPE_FIT_VIEWPORT_QUAD,			numFboSamples));
		group->addChild(new SampleDepthCase				(m_context, "depth",						"Test that depth values are per-sample",												numFboSamples));
		group->addChild(new SampleStencilCase			(m_context, "stencil",						"Test that stencil values are per-sample",												numFboSamples));
		group->addChild(new CoverageMaskInvertCase		(m_context, "sample_coverage_invert",		"Test that non-inverted and inverted sample coverage masks are each other's negations",	numFboSamples));

		group->addChild(new MaskProportionalityCase		(m_context, "proportionality_alpha_to_coverage",
																	"Test the proportionality property of GL_SAMPLE_ALPHA_TO_COVERAGE",
																	MaskProportionalityCase::CASETYPE_ALPHA_TO_COVERAGE, numFboSamples));
		group->addChild(new MaskProportionalityCase		(m_context, "proportionality_sample_coverage",
																	"Test the proportionality property of GL_SAMPLE_COVERAGE",
																	MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE, numFboSamples));
		group->addChild(new MaskProportionalityCase		(m_context, "proportionality_sample_coverage_inverted",
																	"Test the proportionality property of inverted-mask GL_SAMPLE_COVERAGE",
																	MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE_INVERTED, numFboSamples));

		group->addChild(new MaskConstancyCase			(m_context, "constancy_alpha_to_coverage",
																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE",
																	MaskConstancyCase::CASETYPE_ALPHA_TO_COVERAGE, numFboSamples));
		group->addChild(new MaskConstancyCase			(m_context, "constancy_sample_coverage",
																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_COVERAGE",
																	MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE, numFboSamples));
		group->addChild(new MaskConstancyCase			(m_context, "constancy_sample_coverage_inverted",
																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using inverted-mask GL_SAMPLE_COVERAGE",
																	MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE_INVERTED, numFboSamples));
		group->addChild(new MaskConstancyCase			(m_context, "constancy_both",
																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and GL_SAMPLE_COVERAGE",
																	MaskConstancyCase::CASETYPE_BOTH, numFboSamples));
		group->addChild(new MaskConstancyCase			(m_context, "constancy_both_inverted",
																	"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and inverted-mask GL_SAMPLE_COVERAGE",
																	MaskConstancyCase::CASETYPE_BOTH_INVERTED, numFboSamples));
	}
}

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