/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 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 Multisample texture test
 *//*--------------------------------------------------------------------*/

#include "es31fTextureMultisampleTests.hpp"
#include "tcuTestLog.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTextureUtil.hpp"
#include "glsStateQueryUtil.hpp"
#include "tcuRasterizationVerifier.hpp"
#include "gluRenderContext.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluObjectWrapper.hpp"
#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"
#include "gluContextInfo.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"

using namespace glw;

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

using tcu::RasterizationArguments;
using tcu::TriangleSceneSpec;

static std::string sampleMaskToString (const std::vector<deUint32>& bitfield, int numBits)
{
	std::string result(numBits, '0');

	// move from back to front and set chars to 1
	for (int wordNdx = 0; wordNdx < (int)bitfield.size(); ++wordNdx)
	{
		for (int bit = 0; bit < 32; ++bit)
		{
			const int targetCharNdx = numBits - (wordNdx*32+bit) - 1;

			// beginning of the string reached
			if (targetCharNdx < 0)
				return result;

			if ((bitfield[wordNdx] >> bit) & 0x01)
				result[targetCharNdx] = '1';
		}
	}

	return result;
}

/*--------------------------------------------------------------------*//*!
 * \brief Returns the number of words needed to represent mask of given length
 *//*--------------------------------------------------------------------*/
static int getEffectiveSampleMaskWordCount (int highestBitNdx)
{
	const int wordSize	= 32;
	const int maskLen	= highestBitNdx + 1;

	return ((maskLen - 1) / wordSize) + 1; // round_up(mask_len /  wordSize)
}

/*--------------------------------------------------------------------*//*!
 * \brief Creates sample mask with all less significant bits than nthBit set
 *//*--------------------------------------------------------------------*/
static std::vector<deUint32> genAllSetToNthBitSampleMask (int nthBit)
{
	const int				wordSize	= 32;
	const int				numWords	= getEffectiveSampleMaskWordCount(nthBit - 1);
	const deUint32			topWordBits	= (deUint32)(nthBit - (numWords - 1) * wordSize);
	std::vector<deUint32>	mask		(numWords);

	for (int ndx = 0; ndx < numWords - 1; ++ndx)
		mask[ndx] = 0xFFFFFFFF;

	mask[numWords - 1] = (deUint32)((1ULL << topWordBits) - (deUint32)1);
	return mask;
}

/*--------------------------------------------------------------------*//*!
 * \brief Creates sample mask with nthBit set
 *//*--------------------------------------------------------------------*/
static std::vector<deUint32> genSetNthBitSampleMask (int nthBit)
{
	const int				wordSize	= 32;
	const int				numWords	= getEffectiveSampleMaskWordCount(nthBit);
	const deUint32			topWordBits	= (deUint32)(nthBit - (numWords - 1) * wordSize);
	std::vector<deUint32>	mask		(numWords);

	for (int ndx = 0; ndx < numWords - 1; ++ndx)
		mask[ndx] = 0;

	mask[numWords - 1] = (deUint32)(1ULL << topWordBits);
	return mask;
}

std::string specializeShader (Context& context, const char* code)
{
	const glu::ContextType				contextType		= context.getRenderContext().getType();
	const glu::GLSLVersion				glslVersion		= glu::getContextTypeGLSLVersion(contextType);
	std::map<std::string, std::string> specializationMap;

	specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);

	return tcu::StringTemplate(code).specialize(specializationMap);
}

class SamplePosRasterizationTest : public TestCase
{
public:
								SamplePosRasterizationTest	(Context& context, const char* name, const char* desc, int samples);
								~SamplePosRasterizationTest	(void);

private:
	void						init						(void);
	void						deinit						(void);
	IterateResult				iterate						(void);
	void						genMultisampleTexture		(void);
	void						genSamplerProgram			(void);
	bool						testMultisampleTexture		(int sampleNdx);
	void						drawSample					(tcu::Surface& dst, int sampleNdx);
	void						convertToSceneSpec			(TriangleSceneSpec& scene, const tcu::Vec2& samplePos) const;

	struct Triangle
	{
		tcu::Vec4 p1;
		tcu::Vec4 p2;
		tcu::Vec4 p3;
	};

	const int					m_samples;
	const int					m_canvasSize;
	std::vector<Triangle>		m_testTriangles;

	int							m_iteration;
	bool						m_allIterationsOk;

	GLuint						m_texID;
	GLuint						m_vaoID;
	GLuint						m_vboID;
	std::vector<tcu::Vec2>		m_samplePositions;
	int							m_subpixelBits;

	const glu::ShaderProgram*	m_samplerProgram;
	GLint						m_samplerProgramPosLoc;
	GLint						m_samplerProgramSamplerLoc;
	GLint						m_samplerProgramSampleNdxLoc;
};

SamplePosRasterizationTest::SamplePosRasterizationTest (Context& context, const char* name, const char* desc, int samples)
	: TestCase						(context, name, desc)
	, m_samples						(samples)
	, m_canvasSize					(256)
	, m_iteration					(0)
	, m_allIterationsOk				(true)
	, m_texID						(0)
	, m_vaoID						(0)
	, m_vboID						(0)
	, m_subpixelBits				(0)
	, m_samplerProgram				(DE_NULL)
	, m_samplerProgramPosLoc		(-1)
	, m_samplerProgramSamplerLoc	(-1)
	, m_samplerProgramSampleNdxLoc	(-1)
{
}

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

void SamplePosRasterizationTest::init (void)
{
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	GLint					maxSamples	= 0;

	// requirements

	if (m_context.getRenderTarget().getWidth() < m_canvasSize || m_context.getRenderTarget().getHeight() < m_canvasSize)
		throw tcu::NotSupportedError("render target size must be at least " + de::toString(m_canvasSize) + "x" + de::toString(m_canvasSize));

	gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxSamples);
	if (m_samples > maxSamples)
		throw tcu::NotSupportedError("Requested sample count is greater than GL_MAX_COLOR_TEXTURE_SAMPLES");

	m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_COLOR_TEXTURE_SAMPLES = " << maxSamples << tcu::TestLog::EndMessage;

	gl.getIntegerv(GL_SUBPIXEL_BITS, &m_subpixelBits);
	m_testCtx.getLog() << tcu::TestLog::Message << "GL_SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;

	// generate textures & other gl stuff

	m_testCtx.getLog() << tcu::TestLog::Message << "Creating multisample texture" << tcu::TestLog::EndMessage;

	gl.genTextures				(1, &m_texID);
	gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE, m_texID);
	gl.texStorage2DMultisample	(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_RGBA8, m_canvasSize, m_canvasSize, GL_TRUE);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "texStorage2DMultisample");

	gl.genVertexArrays		(1, &m_vaoID);
	gl.bindVertexArray		(m_vaoID);
	GLU_EXPECT_NO_ERROR		(gl.getError(), "bindVertexArray");

	gl.genBuffers			(1, &m_vboID);
	gl.bindBuffer			(GL_ARRAY_BUFFER, m_vboID);
	GLU_EXPECT_NO_ERROR		(gl.getError(), "bindBuffer");

	// generate test scene
	for (int i = 0; i < 20; ++i)
	{
		// vertical spikes
		Triangle tri;
		tri.p1 = tcu::Vec4(((float)i        + 1.0f / (float)(i + 1)) / 20.0f,	 0.0f,	0.0f,	1.0f);
		tri.p2 = tcu::Vec4(((float)i + 0.3f + 1.0f / (float)(i + 1)) / 20.0f,	 0.0f,	0.0f,	1.0f);
		tri.p3 = tcu::Vec4(((float)i        + 1.0f / (float)(i + 1)) / 20.0f,	-1.0f,	0.0f,	1.0f);
		m_testTriangles.push_back(tri);
	}
	for (int i = 0; i < 20; ++i)
	{
		// horisontal spikes
		Triangle tri;
		tri.p1 = tcu::Vec4(-1.0f,	((float)i        + 1.0f / (float)(i + 1)) / 20.0f,	0.0f,	1.0f);
		tri.p2 = tcu::Vec4(-1.0f,	((float)i + 0.3f + 1.0f / (float)(i + 1)) / 20.0f,	0.0f,	1.0f);
		tri.p3 = tcu::Vec4( 0.0f,	((float)i        + 1.0f / (float)(i + 1)) / 20.0f,	0.0f,	1.0f);
		m_testTriangles.push_back(tri);
	}

	for (int i = 0; i < 20; ++i)
	{
		// fan
		const tcu::Vec2 p = tcu::Vec2(deFloatCos(((float)i)/20.0f*DE_PI*2) * 0.5f + 0.5f, deFloatSin(((float)i)/20.0f*DE_PI*2) * 0.5f + 0.5f);
		const tcu::Vec2 d = tcu::Vec2(0.1f, 0.02f);

		Triangle tri;
		tri.p1 = tcu::Vec4(0.4f,			0.4f,			0.0f,	1.0f);
		tri.p2 = tcu::Vec4(p.x(),			p.y(),			0.0f,	1.0f);
		tri.p3 = tcu::Vec4(p.x() + d.x(),	p.y() + d.y(),	0.0f,	1.0f);
		m_testTriangles.push_back(tri);
	}
	{
		Triangle tri;
		tri.p1 = tcu::Vec4(-0.202f, -0.202f, 0.0f, 1.0f);
		tri.p2 = tcu::Vec4(-0.802f, -0.202f, 0.0f, 1.0f);
		tri.p3 = tcu::Vec4(-0.802f, -0.802f, 0.0f, 1.0f);
		m_testTriangles.push_back(tri);
	}

	// generate multisample texture (and query the sample positions in it)
	genMultisampleTexture();

	// verify queried samples are in a valid range
	for (int sampleNdx = 0; sampleNdx < m_samples; ++sampleNdx)
	{
		if (m_samplePositions[sampleNdx].x() < 0.0f || m_samplePositions[sampleNdx].x() > 1.0f ||
			m_samplePositions[sampleNdx].y() < 0.0f || m_samplePositions[sampleNdx].y() > 1.0f)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Sample position of sample " << sampleNdx << " should be in range ([0, 1], [0, 1]). Got " << m_samplePositions[sampleNdx] << tcu::TestLog::EndMessage;
			throw tcu::TestError("invalid sample position");
		}
	}

	// generate sampler program
	genSamplerProgram();
}

void SamplePosRasterizationTest::deinit (void)
{
	if (m_vboID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vboID);
		m_vboID = 0;
	}

	if (m_vaoID)
	{
		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vaoID);
		m_vaoID = 0;
	}

	if (m_texID)
	{
		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texID);
		m_texID = 0;
	}

	if (m_samplerProgram)
	{
		delete m_samplerProgram;
		m_samplerProgram = DE_NULL;
	}
}

SamplePosRasterizationTest::IterateResult SamplePosRasterizationTest::iterate (void)
{
	m_allIterationsOk &= testMultisampleTexture(m_iteration);
	m_iteration++;

	if (m_iteration < m_samples)
		return CONTINUE;

	// End result
	if (m_allIterationsOk)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Pixel comparison failed");

	return STOP;
}

void SamplePosRasterizationTest::genMultisampleTexture (void)
{
	const char* const vertexShaderSource	=	"${GLSL_VERSION_DECL}\n"
												"in highp vec4 a_position;\n"
												"void main (void)\n"
												"{\n"
												"	gl_Position = a_position;\n"
												"}\n";
	const char* const fragmentShaderSource	=	"${GLSL_VERSION_DECL}\n"
												"layout(location = 0) out highp vec4 fragColor;\n"
												"void main (void)\n"
												"{\n"
												"	fragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
												"}\n";

	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources()
																			<< glu::VertexSource(specializeShader(m_context, vertexShaderSource))
																			<< glu::FragmentSource(specializeShader(m_context, fragmentShaderSource)));
	const GLuint				posLoc			= gl.getAttribLocation(program.getProgram(), "a_position");
	GLuint						fboID			= 0;

	if (!program.isOk())
	{
		m_testCtx.getLog() << program;
		throw tcu::TestError("Failed to build shader.");
	}

	gl.bindTexture			(GL_TEXTURE_2D_MULTISAMPLE, m_texID);
	gl.bindVertexArray		(m_vaoID);
	gl.bindBuffer			(GL_ARRAY_BUFFER, m_vboID);

	// Setup fbo for drawing and for sample position query

	m_testCtx.getLog() << tcu::TestLog::Message << "Attaching texture to FBO" << tcu::TestLog::EndMessage;

	gl.genFramebuffers		(1, &fboID);
	gl.bindFramebuffer		(GL_FRAMEBUFFER, fboID);
	gl.framebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_texID, 0);
	GLU_EXPECT_NO_ERROR		(gl.getError(), "framebufferTexture2D");

	// Query sample positions of the multisample texture by querying the sample positions
	// from an fbo which has the multisample texture as attachment.

	m_testCtx.getLog() << tcu::TestLog::Message << "Sample locations:" << tcu::TestLog::EndMessage;

	for (int sampleNdx = 0; sampleNdx < m_samples; ++sampleNdx)
	{
		gls::StateQueryUtil::StateQueryMemoryWriteGuard<float[2]> position;

		gl.getMultisamplefv(GL_SAMPLE_POSITION, (deUint32)sampleNdx, position);
		if (!position.verifyValidity(m_testCtx))
			throw tcu::TestError("Error while querying sample positions");

		m_testCtx.getLog() << tcu::TestLog::Message << "\t" << sampleNdx << ": (" << position[0] << ", " << position[1] << ")" << tcu::TestLog::EndMessage;
		m_samplePositions.push_back(tcu::Vec2(position[0], position[1]));
	}

	// Draw test pattern to texture

	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing test pattern to the texture" << tcu::TestLog::EndMessage;

	gl.bufferData				(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(m_testTriangles.size() * sizeof(Triangle)), &m_testTriangles[0], GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "bufferData");

	gl.viewport					(0, 0, m_canvasSize, m_canvasSize);
	gl.clearColor				(0, 0, 0, 1);
	gl.clear					(GL_COLOR_BUFFER_BIT);
	gl.vertexAttribPointer		(posLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray	(posLoc);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "vertexAttribPointer");

	gl.useProgram				(program.getProgram());
	gl.drawArrays				(GL_TRIANGLES, 0, (glw::GLsizei)(m_testTriangles.size() * 3));
	GLU_EXPECT_NO_ERROR			(gl.getError(), "drawArrays");

	gl.disableVertexAttribArray	(posLoc);
	gl.useProgram				(0);
	gl.deleteFramebuffers		(1, &fboID);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "cleanup");
}

void SamplePosRasterizationTest::genSamplerProgram (void)
{
	const char* const	vertexShaderSource	=	"${GLSL_VERSION_DECL}\n"
												"in highp vec4 a_position;\n"
												"void main (void)\n"
												"{\n"
												"	gl_Position = a_position;\n"
												"}\n";
	const char* const	fragShaderSource	=	"${GLSL_VERSION_DECL}\n"
												"layout(location = 0) out highp vec4 fragColor;\n"
												"uniform highp sampler2DMS u_sampler;\n"
												"uniform highp int u_sample;\n"
												"void main (void)\n"
												"{\n"
												"	fragColor = texelFetch(u_sampler, ivec2(int(floor(gl_FragCoord.x)), int(floor(gl_FragCoord.y))), u_sample);\n"
												"}\n";
	const tcu::ScopedLogSection	section			(m_testCtx.getLog(), "Generate sampler shader", "Generate sampler shader");
	const glw::Functions&		gl			=	m_context.getRenderContext().getFunctions();

	m_samplerProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, vertexShaderSource)) << glu::FragmentSource(specializeShader(m_context, fragShaderSource)));
	m_testCtx.getLog() << *m_samplerProgram;

	if (!m_samplerProgram->isOk())
		throw tcu::TestError("Could not create sampler program.");

	m_samplerProgramPosLoc			= gl.getAttribLocation(m_samplerProgram->getProgram(), "a_position");
	m_samplerProgramSamplerLoc		= gl.getUniformLocation(m_samplerProgram->getProgram(), "u_sampler");
	m_samplerProgramSampleNdxLoc	= gl.getUniformLocation(m_samplerProgram->getProgram(), "u_sample");
}

bool SamplePosRasterizationTest::testMultisampleTexture (int sampleNdx)
{
	tcu::Surface		glSurface(m_canvasSize, m_canvasSize);
	TriangleSceneSpec	scene;

	// Draw sample
	drawSample(glSurface, sampleNdx);

	// Draw reference(s)
	convertToSceneSpec(scene, m_samplePositions[sampleNdx]);

	// Compare
	{
		RasterizationArguments args;
		args.redBits		= m_context.getRenderTarget().getPixelFormat().redBits;
		args.greenBits		= m_context.getRenderTarget().getPixelFormat().greenBits;
		args.blueBits		= m_context.getRenderTarget().getPixelFormat().blueBits;
		args.numSamples		= 0;
		args.subpixelBits	= m_subpixelBits;

		return tcu::verifyTriangleGroupRasterization(glSurface, scene, args, m_testCtx.getLog(), tcu::VERIFICATIONMODE_STRICT);
	}
}

void SamplePosRasterizationTest::drawSample (tcu::Surface& dst, int sampleNdx)
{
	// Downsample using only one sample
	static const tcu::Vec4 fullscreenQuad[] =
	{
		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f)
	};

	const tcu::ScopedLogSection section	(m_testCtx.getLog(), "Test sample position " + de::toString(sampleNdx+1) + "/" + de::toString(m_samples), "Test sample position " + de::toString(sampleNdx+1) + "/" + de::toString(m_samples));
	const glw::Functions&		gl		= m_context.getRenderContext().getFunctions();

	gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE, m_texID);
	gl.bindVertexArray			(m_vaoID);
	gl.bindBuffer				(GL_ARRAY_BUFFER, m_vboID);

	gl.bufferData				(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), &fullscreenQuad[0], GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "bufferData");

	gl.viewport					(0, 0, m_canvasSize, m_canvasSize);
	gl.clearColor				(0, 0, 0, 1);
	gl.clear					(GL_COLOR_BUFFER_BIT);
	gl.vertexAttribPointer		(m_samplerProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray	(m_samplerProgramPosLoc);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "vertexAttribPointer");

	gl.useProgram				(m_samplerProgram->getProgram());
	gl.uniform1i				(m_samplerProgramSamplerLoc, 0);
	gl.uniform1i				(m_samplerProgramSampleNdxLoc, (deInt32)sampleNdx);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "useprogram");

	m_testCtx.getLog() << tcu::TestLog::Message << "Reading from texture with sample index " << sampleNdx << tcu::TestLog::EndMessage;

	gl.drawArrays				(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "drawArrays");

	gl.disableVertexAttribArray	(m_samplerProgramPosLoc);
	gl.useProgram				(0);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "cleanup");

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

void SamplePosRasterizationTest::convertToSceneSpec (TriangleSceneSpec& scene, const tcu::Vec2& samplePos) const
{
	// Triangles are offset from the pixel center by "offset". Move the triangles back to take this into account.
	const tcu::Vec4 offset = tcu::Vec4(samplePos.x() - 0.5f, samplePos.y() - 0.5f, 0.0f, 0.0f) / tcu::Vec4((float)m_canvasSize, (float)m_canvasSize, 1.0f, 1.0f) * 2.0f;

	for (int triangleNdx = 0; triangleNdx < (int)m_testTriangles.size(); ++triangleNdx)
	{
		TriangleSceneSpec::SceneTriangle triangle;

		triangle.positions[0] = m_testTriangles[triangleNdx].p1 - offset;
		triangle.positions[1] = m_testTriangles[triangleNdx].p2 - offset;
		triangle.positions[2] = m_testTriangles[triangleNdx].p3 - offset;

		triangle.sharedEdge[0] = false;
		triangle.sharedEdge[1] = false;
		triangle.sharedEdge[2] = false;

		scene.triangles.push_back(triangle);
	}
}

class SampleMaskCase : public TestCase
{
public:
	enum CaseFlags
	{
		FLAGS_NONE					= 0,
		FLAGS_ALPHA_TO_COVERAGE		= (1ULL << 0),
		FLAGS_SAMPLE_COVERAGE		= (1ULL << 1),
		FLAGS_HIGH_BITS				= (1ULL << 2),
	};

								SampleMaskCase				(Context& context, const char* name, const char* desc, int samples, int flags);
								~SampleMaskCase				(void);

private:
	void						init						(void);
	void						deinit						(void);
	IterateResult				iterate						(void);

	void						genSamplerProgram			(void);
	void						genAlphaProgram				(void);
	void						updateTexture				(int sample);
	bool						verifyTexture				(int sample);
	void						drawSample					(tcu::Surface& dst, int sample);

	glw::GLint					getMaxConformantSampleCount	(glw::GLenum target, glw::GLenum internalFormat);

	const int					m_samples;
	const int					m_canvasSize;
	const int					m_gridsize;
	const int					m_effectiveSampleMaskWordCount;

	int							m_flags;
	int							m_currentSample;
	int							m_allIterationsOk;

	glw::GLuint					m_texID;
	glw::GLuint					m_vaoID;
	glw::GLuint					m_vboID;
	glw::GLuint					m_fboID;

	const glu::ShaderProgram*	m_samplerProgram;
	glw::GLint					m_samplerProgramPosLoc;
	glw::GLint					m_samplerProgramSamplerLoc;
	glw::GLint					m_samplerProgramSampleNdxLoc;

	const glu::ShaderProgram*	m_alphaProgram;
	glw::GLint					m_alphaProgramPosLoc;
};

SampleMaskCase::SampleMaskCase (Context& context, const char* name, const char* desc, int samples, int flags)
	: TestCase						(context, name, desc)
	, m_samples						(samples)
	, m_canvasSize					(256)
	, m_gridsize					(16)
	, m_effectiveSampleMaskWordCount(getEffectiveSampleMaskWordCount(samples - 1))
	, m_flags						(flags)
	, m_currentSample				(-1)
	, m_allIterationsOk				(true)
	, m_texID						(0)
	, m_vaoID						(0)
	, m_vboID						(0)
	, m_fboID						(0)
	, m_samplerProgram				(DE_NULL)
	, m_samplerProgramPosLoc		(-1)
	, m_samplerProgramSamplerLoc	(-1)
	, m_samplerProgramSampleNdxLoc	(-1)
	, m_alphaProgram				(DE_NULL)
	, m_alphaProgramPosLoc			(-1)
{
}

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

void SampleMaskCase::init (void)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	glw::GLint				maxSamples			= 0;
	glw::GLint				maxSampleMaskWords	= 0;

	// requirements

	if (m_context.getRenderTarget().getWidth() < m_canvasSize || m_context.getRenderTarget().getHeight() < m_canvasSize)
		throw tcu::NotSupportedError("render target size must be at least " + de::toString(m_canvasSize) + "x" + de::toString(m_canvasSize));

	gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
	if (m_effectiveSampleMaskWordCount > maxSampleMaskWords)
		throw tcu::NotSupportedError("Test requires larger GL_MAX_SAMPLE_MASK_WORDS");

	maxSamples = getMaxConformantSampleCount(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8);
	if (m_samples > maxSamples)
		throw tcu::NotSupportedError("Requested sample count is greater than glGetInternalformativ(GL_SAMPLES) for this target/format");

	m_testCtx.getLog() << tcu::TestLog::Message << "glGetInternalformativ(GL_SAMPLES) = " << maxSamples << tcu::TestLog::EndMessage;

	// Don't even try to test high bits if there are none

	if ((m_flags & FLAGS_HIGH_BITS) && (m_samples % 32 == 0))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Sample count is multiple of word size. No unused high bits in sample mask.\nSkipping." << tcu::TestLog::EndMessage;
		throw tcu::NotSupportedError("Test requires unused high bits (sample count not multiple of 32)");
	}

	// generate textures

	m_testCtx.getLog() << tcu::TestLog::Message << "Creating multisample texture with sample count " << m_samples << tcu::TestLog::EndMessage;

	gl.genTextures				(1, &m_texID);
	gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE, m_texID);
	gl.texStorage2DMultisample	(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_RGBA8, m_canvasSize, m_canvasSize, GL_FALSE);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "texStorage2DMultisample");

	// attach texture to fbo

	m_testCtx.getLog() << tcu::TestLog::Message << "Attaching texture to FBO" << tcu::TestLog::EndMessage;

	gl.genFramebuffers		(1, &m_fboID);
	gl.bindFramebuffer		(GL_FRAMEBUFFER, m_fboID);
	gl.framebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_texID, 0);
	GLU_EXPECT_NO_ERROR		(gl.getError(), "framebufferTexture2D");

	// buffers

	gl.genVertexArrays		(1, &m_vaoID);
	GLU_EXPECT_NO_ERROR		(gl.getError(), "genVertexArrays");

	gl.genBuffers			(1, &m_vboID);
	gl.bindBuffer			(GL_ARRAY_BUFFER, m_vboID);
	GLU_EXPECT_NO_ERROR		(gl.getError(), "genBuffers");

	// generate grid pattern
	{
		std::vector<tcu::Vec4> gridData(m_gridsize*m_gridsize*6);

		for (int y = 0; y < m_gridsize; ++y)
		for (int x = 0; x < m_gridsize; ++x)
		{
			gridData[(y * m_gridsize + x)*6 + 0] = tcu::Vec4(((float)(x+0) / (float)m_gridsize) * 2.0f - 1.0f, ((float)(y+0) / (float)m_gridsize) * 2.0f - 1.0f, 0.0f, 1.0f);
			gridData[(y * m_gridsize + x)*6 + 1] = tcu::Vec4(((float)(x+0) / (float)m_gridsize) * 2.0f - 1.0f, ((float)(y+1) / (float)m_gridsize) * 2.0f - 1.0f, 0.0f, 1.0f);
			gridData[(y * m_gridsize + x)*6 + 2] = tcu::Vec4(((float)(x+1) / (float)m_gridsize) * 2.0f - 1.0f, ((float)(y+1) / (float)m_gridsize) * 2.0f - 1.0f, 0.0f, 1.0f);
			gridData[(y * m_gridsize + x)*6 + 3] = tcu::Vec4(((float)(x+0) / (float)m_gridsize) * 2.0f - 1.0f, ((float)(y+0) / (float)m_gridsize) * 2.0f - 1.0f, 0.0f, 1.0f);
			gridData[(y * m_gridsize + x)*6 + 4] = tcu::Vec4(((float)(x+1) / (float)m_gridsize) * 2.0f - 1.0f, ((float)(y+1) / (float)m_gridsize) * 2.0f - 1.0f, 0.0f, 1.0f);
			gridData[(y * m_gridsize + x)*6 + 5] = tcu::Vec4(((float)(x+1) / (float)m_gridsize) * 2.0f - 1.0f, ((float)(y+0) / (float)m_gridsize) * 2.0f - 1.0f, 0.0f, 1.0f);
		}

		gl.bufferData			(GL_ARRAY_BUFFER, (int)(gridData.size() * sizeof(tcu::Vec4)), gridData[0].getPtr(), GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR		(gl.getError(), "bufferData");
	}

	// generate programs

	genSamplerProgram();
	genAlphaProgram();
}

void SampleMaskCase::deinit (void)
{
	if (m_texID)
	{
		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texID);
		m_texID = 0;
	}
	if (m_vaoID)
	{
		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vaoID);
		m_vaoID = 0;
	}
	if (m_vboID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vboID);
		m_vboID = 0;
	}
	if (m_fboID)
	{
		m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_fboID);
		m_fboID = 0;
	}

	if (m_samplerProgram)
	{
		delete m_samplerProgram;
		m_samplerProgram = DE_NULL;
	}
	if (m_alphaProgram)
	{
		delete m_alphaProgram;
		m_alphaProgram = DE_NULL;
	}
}

SampleMaskCase::IterateResult SampleMaskCase::iterate (void)
{
	const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Iteration", (m_currentSample == -1) ? ("Verifying with zero mask") : (std::string() + "Verifying sample " + de::toString(m_currentSample + 1) + "/" + de::toString(m_samples)));

	bool iterationOk;

	// Mask only one sample, clear rest

	updateTexture(m_currentSample);

	// Verify only one sample set is in the texture

	iterationOk = verifyTexture(m_currentSample);
	if (!iterationOk)
		m_allIterationsOk = false;

	m_currentSample++;
	if (m_currentSample < m_samples)
		return CONTINUE;

	// End result

	if (m_allIterationsOk)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else if (m_flags & FLAGS_HIGH_BITS)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unused mask bits have effect");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Sample test failed");

	return STOP;
}

void SampleMaskCase::genSamplerProgram (void)
{
	const char* const	vertexShaderSource			= "${GLSL_VERSION_DECL}\n"
													  "in highp vec4 a_position;\n"
													  "void main (void)\n"
													  "{\n"
													  "	gl_Position = a_position;\n"
													  "}\n";
	const char* const	fragShaderSource			= "${GLSL_VERSION_DECL}\n"
													  "layout(location = 0) out highp vec4 fragColor;\n"
													  "uniform highp sampler2DMS u_sampler;\n"
													  "uniform highp int u_sample;\n"
													  "void main (void)\n"
													  "{\n"
													  "	highp float correctCoverage = 0.0;\n"
													  "	highp float incorrectCoverage = 0.0;\n"
													  "	highp ivec2 texelPos = ivec2(int(floor(gl_FragCoord.x)), int(floor(gl_FragCoord.y)));\n"
													  "\n"
													  "	for (int sampleNdx = 0; sampleNdx < ${NUMSAMPLES}; ++sampleNdx)\n"
													  "	{\n"
													  "		highp float sampleColor = texelFetch(u_sampler, texelPos, sampleNdx).r;\n"
													  "		if (sampleNdx == u_sample)\n"
													  "			correctCoverage += sampleColor;\n"
													  "		else\n"
													  "			incorrectCoverage += sampleColor;\n"
													  "	}\n"
													  "	fragColor = vec4(correctCoverage, incorrectCoverage, 0.0, 1.0);\n"
													  "}\n";
	const tcu::ScopedLogSection			section		(m_testCtx.getLog(), "GenerateSamplerShader", "Generate sampler shader");
	const glw::Functions&				gl			= m_context.getRenderContext().getFunctions();
	std::map<std::string, std::string>	args;
	const glu::GLSLVersion				glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

	args["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
	args["NUMSAMPLES"] = de::toString(m_samples);

	m_samplerProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, vertexShaderSource)) << glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
	m_testCtx.getLog() << *m_samplerProgram;

	if (!m_samplerProgram->isOk())
		throw tcu::TestError("Could not create sampler program.");

	m_samplerProgramPosLoc			= gl.getAttribLocation(m_samplerProgram->getProgram(), "a_position");
	m_samplerProgramSamplerLoc		= gl.getUniformLocation(m_samplerProgram->getProgram(), "u_sampler");
	m_samplerProgramSampleNdxLoc	= gl.getUniformLocation(m_samplerProgram->getProgram(), "u_sample");
}

void SampleMaskCase::genAlphaProgram (void)
{
	const char* const	vertexShaderSource	=	"${GLSL_VERSION_DECL}\n"
												"in highp vec4 a_position;\n"
												"out highp float v_alpha;\n"
												"void main (void)\n"
												"{\n"
												"	gl_Position = a_position;\n"
												"	v_alpha = (a_position.x * 0.5 + 0.5)*(a_position.y * 0.5 + 0.5);\n"
												"}\n";
	const char* const	fragShaderSource	=	"${GLSL_VERSION_DECL}\n"
												"layout(location = 0) out highp vec4 fragColor;\n"
												"in mediump float v_alpha;\n"
												"void main (void)\n"
												"{\n"
												"	fragColor = vec4(1.0, 1.0, 1.0, v_alpha);\n"
												"}\n";
	const glw::Functions&		gl			=	m_context.getRenderContext().getFunctions();

	m_alphaProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, vertexShaderSource)) << glu::FragmentSource(specializeShader(m_context, fragShaderSource)));

	if (!m_alphaProgram->isOk())
	{
		m_testCtx.getLog() << *m_alphaProgram;
		throw tcu::TestError("Could not create aplha program.");
	}

	m_alphaProgramPosLoc = gl.getAttribLocation(m_alphaProgram->getProgram(), "a_position");
}

void SampleMaskCase::updateTexture (int sample)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// prepare draw

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);
	gl.viewport(0, 0, m_canvasSize, m_canvasSize);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);

	// clear all samples

	m_testCtx.getLog() << tcu::TestLog::Message << "Clearing image" << tcu::TestLog::EndMessage;
	gl.clear(GL_COLOR_BUFFER_BIT);

	// set mask state

	if (m_flags & FLAGS_HIGH_BITS)
	{
		const std::vector<deUint32> bitmask			= genSetNthBitSampleMask(sample);
		const std::vector<deUint32>	effectiveMask	= genAllSetToNthBitSampleMask(m_samples);
		std::vector<deUint32>		totalBitmask	(effectiveMask.size());

		DE_ASSERT((int)totalBitmask.size() == m_effectiveSampleMaskWordCount);

		// set some arbitrary high bits to non-effective bits
		for (int wordNdx = 0; wordNdx < (int)effectiveMask.size(); ++wordNdx)
		{
			const deUint32 randomMask	= (deUint32)deUint32Hash(wordNdx << 2 ^ sample);
			const deUint32 sampleMask	= (wordNdx < (int)bitmask.size()) ? (bitmask[wordNdx]) : (0);
			const deUint32 maskMask		= effectiveMask[wordNdx];

			totalBitmask[wordNdx] = (sampleMask & maskMask) | (randomMask & ~maskMask);
		}

		m_testCtx.getLog() << tcu::TestLog::Message << "Setting sample mask to 0b" << sampleMaskToString(totalBitmask, (int)totalBitmask.size() * 32) << tcu::TestLog::EndMessage;

		gl.enable(GL_SAMPLE_MASK);
		for (int wordNdx = 0; wordNdx < m_effectiveSampleMaskWordCount; ++wordNdx)
		{
			const GLbitfield wordmask = (wordNdx < (int)totalBitmask.size()) ? ((GLbitfield)(totalBitmask[wordNdx])) : (0);
			gl.sampleMaski((deUint32)wordNdx, wordmask);
		}
	}
	else
	{
		const std::vector<deUint32> bitmask = genSetNthBitSampleMask(sample);
		DE_ASSERT((int)bitmask.size() <= m_effectiveSampleMaskWordCount);

		m_testCtx.getLog() << tcu::TestLog::Message << "Setting sample mask to 0b" << sampleMaskToString(bitmask, m_samples) << tcu::TestLog::EndMessage;

		gl.enable(GL_SAMPLE_MASK);
		for (int wordNdx = 0; wordNdx < m_effectiveSampleMaskWordCount; ++wordNdx)
		{
			const GLbitfield wordmask = (wordNdx < (int)bitmask.size()) ? ((GLbitfield)(bitmask[wordNdx])) : (0);
			gl.sampleMaski((deUint32)wordNdx, wordmask);
		}
	}
	if (m_flags & FLAGS_ALPHA_TO_COVERAGE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Enabling alpha to coverage." << tcu::TestLog::EndMessage;
		gl.enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
	}
	if (m_flags & FLAGS_SAMPLE_COVERAGE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Enabling sample coverage. Varying sample coverage for grid cells." << tcu::TestLog::EndMessage;
		gl.enable(GL_SAMPLE_COVERAGE);
	}

	// draw test pattern

	m_testCtx.getLog() << tcu::TestLog::Message << "Drawing test grid" << tcu::TestLog::EndMessage;

	gl.bindVertexArray			(m_vaoID);
	gl.bindBuffer				(GL_ARRAY_BUFFER, m_vboID);
	gl.vertexAttribPointer		(m_alphaProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray	(m_alphaProgramPosLoc);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "vertexAttribPointer");

	gl.useProgram				(m_alphaProgram->getProgram());

	for (int y = 0; y < m_gridsize; ++y)
	for (int x = 0; x < m_gridsize; ++x)
	{
		if (m_flags & FLAGS_SAMPLE_COVERAGE)
			gl.sampleCoverage((float)(y*m_gridsize + x) / float(m_gridsize*m_gridsize), GL_FALSE);

		gl.drawArrays				(GL_TRIANGLES, (y*m_gridsize + x) * 6, 6);
		GLU_EXPECT_NO_ERROR			(gl.getError(), "drawArrays");
	}

	// clean state

	gl.disableVertexAttribArray	(m_alphaProgramPosLoc);
	gl.useProgram				(0);
	gl.bindFramebuffer			(GL_FRAMEBUFFER, 0);
	gl.disable					(GL_SAMPLE_MASK);
	gl.disable					(GL_SAMPLE_ALPHA_TO_COVERAGE);
	gl.disable					(GL_SAMPLE_COVERAGE);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "clean");
}

bool SampleMaskCase::verifyTexture (int sample)
{
	tcu::Surface	result		(m_canvasSize, m_canvasSize);
	tcu::Surface	errorMask	(m_canvasSize, m_canvasSize);
	bool			error		= false;

	tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());

	// Draw sample:
	//	Sample sampleNdx is set to red channel
	//	Other samples are set to green channel
	drawSample(result, sample);

	// Check surface contains only sampleNdx
	for (int y = 0; y < m_canvasSize; ++y)
	for (int x = 0; x < m_canvasSize; ++x)
	{
		const tcu::RGBA color					= result.getPixel(x, y);

		// Allow missing coverage with FLAGS_ALPHA_TO_COVERAGE and FLAGS_SAMPLE_COVERAGE, or if there are no samples enabled
		const bool		allowMissingCoverage	= ((m_flags & (FLAGS_ALPHA_TO_COVERAGE | FLAGS_SAMPLE_COVERAGE)) != 0) || (sample == -1);

		// disabled sample was written to
		if (color.getGreen() != 0)
		{
			error = true;
			errorMask.setPixel(x, y, tcu::RGBA::red());
		}
		// enabled sample was not written to
		else if (color.getRed() != 255 && !allowMissingCoverage)
		{
			error = true;
			errorMask.setPixel(x, y, tcu::RGBA::red());
		}
	}

	if (error)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message << "Image verification failed, disabled samples found." << tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("VerificationResult", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		result)
			<< tcu::TestLog::Image("ErrorMask",	"Error Mask",	errorMask)
			<< tcu::TestLog::EndImageSet;
		return false;
	}
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Image verification ok, no disabled samples found." << tcu::TestLog::EndMessage;
		return true;
	}
}

void SampleMaskCase::drawSample (tcu::Surface& dst, int sample)
{
	// Downsample using only one sample
	static const tcu::Vec4 fullscreenQuad[] =
	{
		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f)
	};

	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	glu::Buffer				vertexBuffer	(m_context.getRenderContext());

	gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE, m_texID);
	gl.bindVertexArray			(m_vaoID);

	gl.bindBuffer				(GL_ARRAY_BUFFER, *vertexBuffer);
	gl.bufferData				(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), &fullscreenQuad[0], GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "bufferData");

	gl.viewport					(0, 0, m_canvasSize, m_canvasSize);
	gl.clearColor				(0, 0, 0, 1);
	gl.clear					(GL_COLOR_BUFFER_BIT);
	gl.vertexAttribPointer		(m_samplerProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray	(m_samplerProgramPosLoc);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "vertexAttribPointer");

	gl.useProgram				(m_samplerProgram->getProgram());
	gl.uniform1i				(m_samplerProgramSamplerLoc, 0);
	gl.uniform1i				(m_samplerProgramSampleNdxLoc, (deInt32)sample);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "useprogram");

	m_testCtx.getLog() << tcu::TestLog::Message << "Reading from texture with sampler shader, u_sample = " << sample << tcu::TestLog::EndMessage;

	gl.drawArrays				(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "drawArrays");

	gl.disableVertexAttribArray	(m_samplerProgramPosLoc);
	gl.useProgram				(0);
	GLU_EXPECT_NO_ERROR			(gl.getError(), "cleanup");

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

glw::GLint SampleMaskCase::getMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat)
{
	deInt32					maxTextureSamples	= 0;
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	if (m_context.getContextInfo().isExtensionSupported("GL_NV_internalformat_sample_query"))
	{
		glw::GLint gl_sample_counts = 0;
		gl.getInternalformativ(target, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &gl_sample_counts);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_NUM_SAMPLE_COUNTS pname");
		/* Check and return the first conformant sample count */
		glw::GLint* gl_supported_samples = new glw::GLint[gl_sample_counts];
		if (gl_supported_samples)
		{
			gl.getInternalformativ(target, internalFormat, GL_SAMPLES, gl_sample_counts, gl_supported_samples);
			for (glw::GLint i = 0; i < gl_sample_counts; i++)
			{
				glw::GLint isConformant = 0;
				gl.getInternalformatSampleivNV(target, internalFormat, gl_supported_samples[i], GL_CONFORMANT_NV, 1,
					&isConformant);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformatSampleivNV() call(s) failed");
				if (isConformant && gl_supported_samples[i] > maxTextureSamples)
				{
					maxTextureSamples = gl_supported_samples[i];
				}
			}
			delete[] gl_supported_samples;
		}
	}
	else
	{
		gl.getInternalformativ(target, internalFormat, GL_SAMPLES, 1, &maxTextureSamples);
	}
	return maxTextureSamples;
}


class MultisampleTextureUsageCase : public TestCase
{
public:

	enum TextureType
	{
		TEXTURE_COLOR_2D = 0,
		TEXTURE_COLOR_2D_ARRAY,
		TEXTURE_INT_2D,
		TEXTURE_INT_2D_ARRAY,
		TEXTURE_UINT_2D,
		TEXTURE_UINT_2D_ARRAY,
		TEXTURE_DEPTH_2D,
		TEXTURE_DEPTH_2D_ARRAY,

		TEXTURE_LAST
	};

						MultisampleTextureUsageCase		(Context& ctx, const char* name, const char* desc, int samples, TextureType type);
						~MultisampleTextureUsageCase	(void);

private:
	void				init							(void);
	void				deinit							(void);
	IterateResult		iterate							(void);

	void				genDrawShader					(void);
	void				genSamplerShader				(void);

	void				renderToTexture					(float value);
	void				sampleTexture					(tcu::Surface& dst, float value);
	bool				verifyImage						(const tcu::Surface& dst);

	static const int	s_textureSize					= 256;
	static const int	s_textureArraySize				= 8;
	static const int	s_textureLayer					= 3;

	const TextureType	m_type;
	const int			m_numSamples;

	glw::GLuint			m_fboID;
	glw::GLuint			m_vaoID;
	glw::GLuint			m_textureID;

	glu::ShaderProgram*	m_drawShader;
	glu::ShaderProgram*	m_samplerShader;

	const bool			m_isColorFormat;
	const bool			m_isSignedFormat;
	const bool			m_isUnsignedFormat;
	const bool			m_isDepthFormat;
	const bool			m_isArrayType;
};

MultisampleTextureUsageCase::MultisampleTextureUsageCase (Context& ctx, const char* name, const char* desc, int samples, TextureType type)
	: TestCase			(ctx, name, desc)
	, m_type			(type)
	, m_numSamples		(samples)
	, m_fboID			(0)
	, m_vaoID			(0)
	, m_textureID		(0)
	, m_drawShader		(DE_NULL)
	, m_samplerShader	(DE_NULL)
	, m_isColorFormat	(m_type == TEXTURE_COLOR_2D	|| m_type == TEXTURE_COLOR_2D_ARRAY)
	, m_isSignedFormat	(m_type == TEXTURE_INT_2D	|| m_type == TEXTURE_INT_2D_ARRAY)
	, m_isUnsignedFormat(m_type == TEXTURE_UINT_2D	|| m_type == TEXTURE_UINT_2D_ARRAY)
	, m_isDepthFormat	(m_type == TEXTURE_DEPTH_2D	|| m_type == TEXTURE_DEPTH_2D_ARRAY)
	, m_isArrayType		(m_type == TEXTURE_COLOR_2D_ARRAY || m_type == TEXTURE_INT_2D_ARRAY || m_type == TEXTURE_UINT_2D_ARRAY || m_type == TEXTURE_DEPTH_2D_ARRAY)
{
	DE_ASSERT(m_type < TEXTURE_LAST);
}

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

void MultisampleTextureUsageCase::init (void)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const glw::GLenum		internalFormat		= (m_isColorFormat) ? (GL_R8) : (m_isSignedFormat) ? (GL_R8I) : (m_isUnsignedFormat) ? (GL_R8UI) : (m_isDepthFormat) ? (GL_DEPTH_COMPONENT32F) : (0);
	const glw::GLenum		textureTarget		= (m_isArrayType) ? (GL_TEXTURE_2D_MULTISAMPLE_ARRAY) : (GL_TEXTURE_2D_MULTISAMPLE);
	const glw::GLenum		fboAttachment		= (m_isDepthFormat) ? (GL_DEPTH_ATTACHMENT) : (GL_COLOR_ATTACHMENT0);
	const bool				supportsES32orGL45	= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
												  glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));

	DE_ASSERT(internalFormat);

	// requirements

	if (m_isArrayType && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
		throw tcu::NotSupportedError("Test requires OES_texture_storage_multisample_2d_array extension");
	if (m_context.getRenderTarget().getWidth() < s_textureSize || m_context.getRenderTarget().getHeight() < s_textureSize)
		throw tcu::NotSupportedError("render target size must be at least " + de::toString(static_cast<int>(s_textureSize)) + "x" + de::toString(static_cast<int>(s_textureSize)));

	{
		glw::GLint maxSamples = 0;
		gl.getInternalformativ(textureTarget, internalFormat, GL_SAMPLES, 1, &maxSamples);

		if (m_numSamples > maxSamples)
			throw tcu::NotSupportedError("Requested sample count is greater than supported");

		m_testCtx.getLog() << tcu::TestLog::Message << "Max sample count for " << glu::getTextureFormatStr(internalFormat) << ": " << maxSamples << tcu::TestLog::EndMessage;
	}

	{
		GLint maxTextureSize = 0;
		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);

		if (s_textureSize > maxTextureSize)
			throw tcu::NotSupportedError("Larger GL_MAX_TEXTURE_SIZE is required");
	}

	if (m_isArrayType)
	{
		GLint maxTextureLayers = 0;
		gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);

		if (s_textureArraySize > maxTextureLayers)
			throw tcu::NotSupportedError("Larger GL_MAX_ARRAY_TEXTURE_LAYERS is required");
	}

	// create texture

	m_testCtx.getLog() << tcu::TestLog::Message << "Creating multisample " << ((m_isDepthFormat) ? ("depth") : ("")) << " texture" << ((m_isArrayType) ? (" array") : ("")) << tcu::TestLog::EndMessage;

	gl.genTextures(1, &m_textureID);
	gl.bindTexture(textureTarget, m_textureID);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bind texture");

	if (m_isArrayType)
		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, m_numSamples, internalFormat, s_textureSize, s_textureSize, s_textureArraySize, GL_FALSE);
	else
		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_numSamples, internalFormat, s_textureSize, s_textureSize, GL_FALSE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texstorage");

	// create fbo for drawing

	gl.genFramebuffers(1, &m_fboID);
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);

	if (m_isArrayType)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Attaching multisample texture array layer " << static_cast<int>(s_textureLayer) << " to fbo" << tcu::TestLog::EndMessage;
		gl.framebufferTextureLayer(GL_FRAMEBUFFER, fboAttachment, m_textureID, 0, s_textureLayer);
	}
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Attaching multisample texture to fbo" << tcu::TestLog::EndMessage;
		gl.framebufferTexture2D(GL_FRAMEBUFFER, fboAttachment, textureTarget, m_textureID, 0);
	}
	GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");

	// create vao if context is GL4.5
	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
		gl.genVertexArrays(1, &m_vaoID);

	// create shader for rendering to fbo
	genDrawShader();

	// create shader for sampling the texture rendered to
	genSamplerShader();
}

void MultisampleTextureUsageCase::deinit (void)
{
	if (m_textureID)
	{
		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textureID);
		m_textureID = 0;
	}

	if (m_fboID)
	{
		m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_fboID);
		m_fboID = 0;
	}

	if (m_vaoID)
	{
		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vaoID);
		m_vaoID = 0;
	}

	if (m_drawShader)
	{
		delete m_drawShader;
		m_drawShader = DE_NULL;
	}

	if (m_samplerShader)
	{
		delete m_samplerShader;
		m_samplerShader = DE_NULL;
	}
}

MultisampleTextureUsageCase::IterateResult MultisampleTextureUsageCase::iterate (void)
{
	const tcu::ScopedLogSection	section			(m_testCtx.getLog(), "Sample", "Render to texture and sample texture");
	tcu::Surface				result			(s_textureSize, s_textureSize);
	const float					minValue		= (m_isColorFormat || m_isDepthFormat) ? (0.0f) : (m_isSignedFormat) ? (-100.0f) : (m_isUnsignedFormat) ? (0.0f)	: ( 1.0f);
	const float					maxValue		= (m_isColorFormat || m_isDepthFormat) ? (1.0f) : (m_isSignedFormat) ? ( 100.0f) : (m_isUnsignedFormat) ? (200.0f)	: (-1.0f);
	de::Random					rnd				(deUint32Hash((deUint32)m_type));
	const float					rawValue		= rnd.getFloat(minValue, maxValue);
	const float					preparedValue	= (m_isSignedFormat || m_isUnsignedFormat) ? (deFloatFloor(rawValue)) : (rawValue);

	// draw to fbo with a random value

	renderToTexture(preparedValue);

	// draw from texture to front buffer

	sampleTexture(result, preparedValue);

	// result is ok?

	if (verifyImage(result))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");

	return STOP;
}

void MultisampleTextureUsageCase::genDrawShader (void)
{
	const tcu::ScopedLogSection section(m_testCtx.getLog(), "RenderShader", "Generate render-to-texture shader");

	static const char* const	vertexShaderSource =		"${GLSL_VERSION_DECL}\n"
															"in highp vec4 a_position;\n"
															"void main (void)\n"
															"{\n"
															"	gl_Position = a_position;\n"
															"}\n";
	static const char* const	fragmentShaderSourceColor =	"${GLSL_VERSION_DECL}\n"
															"layout(location = 0) out highp ${OUTTYPE} fragColor;\n"
															"uniform highp float u_writeValue;\n"
															"void main (void)\n"
															"{\n"
															"	fragColor = ${OUTTYPE}(vec4(u_writeValue, 1.0, 1.0, 1.0));\n"
															"}\n";
	static const char* const	fragmentShaderSourceDepth =	"${GLSL_VERSION_DECL}\n"
															"layout(location = 0) out highp vec4 fragColor;\n"
															"uniform highp float u_writeValue;\n"
															"void main (void)\n"
															"{\n"
															"	fragColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
															"	gl_FragDepth = u_writeValue;\n"
															"}\n";
	const char* const			fragmentSource =			(m_isDepthFormat) ? (fragmentShaderSourceDepth) : (fragmentShaderSourceColor);

	std::map<std::string, std::string> fragmentArguments;

	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
	fragmentArguments["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);

	if (m_isColorFormat || m_isDepthFormat)
		fragmentArguments["OUTTYPE"] = "vec4";
	else if (m_isSignedFormat)
		fragmentArguments["OUTTYPE"] = "ivec4";
	else if (m_isUnsignedFormat)
		fragmentArguments["OUTTYPE"] = "uvec4";
	else
		DE_ASSERT(DE_FALSE);

	m_drawShader = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, vertexShaderSource)) << glu::FragmentSource(tcu::StringTemplate(fragmentSource).specialize(fragmentArguments)));
	m_testCtx.getLog() << *m_drawShader;

	if (!m_drawShader->isOk())
		throw tcu::TestError("could not build shader");
}

void MultisampleTextureUsageCase::genSamplerShader (void)
{
	const tcu::ScopedLogSection section(m_testCtx.getLog(), "SamplerShader", "Generate texture sampler shader");

	static const char* const vertexShaderSource =	"${GLSL_VERSION_DECL}\n"
													"in highp vec4 a_position;\n"
													"out highp float v_gradient;\n"
													"void main (void)\n"
													"{\n"
													"	gl_Position = a_position;\n"
													"	v_gradient = a_position.x * 0.5 + 0.5;\n"
													"}\n";
	static const char* const fragmentShaderSource =	"${GLSL_VERSION_DECL}\n"
													"${EXTENSION_STATEMENT}"
													"layout(location = 0) out highp vec4 fragColor;\n"
													"uniform highp ${SAMPLERTYPE} u_sampler;\n"
													"uniform highp int u_maxSamples;\n"
													"uniform highp int u_layer;\n"
													"uniform highp float u_cmpValue;\n"
													"in highp float v_gradient;\n"
													"void main (void)\n"
													"{\n"
													"	const highp vec4 okColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
													"	const highp vec4 failColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
													"	const highp float epsilon = ${EPSILON};\n"
													"\n"
													"	highp int sampleNdx = clamp(int(floor(v_gradient * float(u_maxSamples))), 0, u_maxSamples-1);\n"
													"	highp float value = float(texelFetch(u_sampler, ${FETCHPOS}, sampleNdx).r);\n"
													"	fragColor = (abs(u_cmpValue - value) < epsilon) ? (okColor) : (failColor);\n"
													"}\n";

	std::map<std::string, std::string> fragmentArguments;

	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
	fragmentArguments["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);

	const bool supportsES32orGL45 =
		glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
		glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));

	if (m_isArrayType)
		fragmentArguments["FETCHPOS"] = "ivec3(floor(gl_FragCoord.xy), u_layer)";
	else
		fragmentArguments["FETCHPOS"] = "ivec2(floor(gl_FragCoord.xy))";

	if (m_isColorFormat || m_isDepthFormat)
		fragmentArguments["EPSILON"] = "0.1";
	else
		fragmentArguments["EPSILON"] = "1.0";

	if (m_isArrayType && !supportsES32orGL45)
		fragmentArguments["EXTENSION_STATEMENT"] = "#extension GL_OES_texture_storage_multisample_2d_array : require\n";
	else
		fragmentArguments["EXTENSION_STATEMENT"] = "";

	switch (m_type)
	{
		case TEXTURE_COLOR_2D:			fragmentArguments["SAMPLERTYPE"] = "sampler2DMS";		break;
		case TEXTURE_COLOR_2D_ARRAY:	fragmentArguments["SAMPLERTYPE"] = "sampler2DMSArray";	break;
		case TEXTURE_INT_2D:			fragmentArguments["SAMPLERTYPE"] = "isampler2DMS";		break;
		case TEXTURE_INT_2D_ARRAY:		fragmentArguments["SAMPLERTYPE"] = "isampler2DMSArray";	break;
		case TEXTURE_UINT_2D:			fragmentArguments["SAMPLERTYPE"] = "usampler2DMS";		break;
		case TEXTURE_UINT_2D_ARRAY:		fragmentArguments["SAMPLERTYPE"] = "usampler2DMSArray";	break;
		case TEXTURE_DEPTH_2D:			fragmentArguments["SAMPLERTYPE"] = "sampler2DMS";		break;
		case TEXTURE_DEPTH_2D_ARRAY:	fragmentArguments["SAMPLERTYPE"] = "sampler2DMSArray";	break;

		default:
			DE_ASSERT(DE_FALSE);
	}

	m_samplerShader = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, vertexShaderSource)) << glu::FragmentSource(tcu::StringTemplate(fragmentShaderSource).specialize(fragmentArguments)));
	m_testCtx.getLog() << *m_samplerShader;

	if (!m_samplerShader->isOk())
		throw tcu::TestError("could not build shader");
}

void MultisampleTextureUsageCase::renderToTexture (float value)
{
	static const tcu::Vec4 fullscreenQuad[] =
	{
		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
	};

	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const int				posLocation			= gl.getAttribLocation(m_drawShader->getProgram(), "a_position");
	const int				valueLocation		= gl.getUniformLocation(m_drawShader->getProgram(), "u_writeValue");
	glu::Buffer				vertexAttibBuffer	(m_context.getRenderContext());

	m_testCtx.getLog() << tcu::TestLog::Message << "Filling multisample texture with value " << value  << tcu::TestLog::EndMessage;

	// upload data

	gl.bindBuffer(GL_ARRAY_BUFFER, *vertexAttibBuffer);
	gl.bufferData(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), fullscreenQuad[0].getPtr(), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bufferdata");

	// clear buffer

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);
	gl.viewport(0, 0, s_textureSize, s_textureSize);

	if (m_isColorFormat)
	{
		const float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
		gl.clearBufferfv(GL_COLOR, 0, clearColor);
	}
	else if (m_isSignedFormat)
	{
		const deInt32 clearColor[4] = { 0, 0, 0, 0 };
		gl.clearBufferiv(GL_COLOR, 0, clearColor);
	}
	else if (m_isUnsignedFormat)
	{
		const deUint32 clearColor[4] = { 0, 0, 0, 0 };
		gl.clearBufferuiv(GL_COLOR, 0, clearColor);
	}
	else if (m_isDepthFormat)
	{
		const float clearDepth = 0.5f;
		gl.clearBufferfv(GL_DEPTH, 0, &clearDepth);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "clear buffer");

	// setup shader and draw
	if (m_vaoID)
		gl.bindVertexArray(m_vaoID);

	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray(posLocation);

	gl.useProgram(m_drawShader->getProgram());
	gl.uniform1f(valueLocation, value);

	GLU_EXPECT_NO_ERROR(gl.getError(), "setup draw");

	if (m_isDepthFormat)
	{
		gl.enable(GL_DEPTH_TEST);
		gl.depthFunc(GL_ALWAYS);
	}

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");

	// clean state

	if (m_isDepthFormat)
		gl.disable(GL_DEPTH_TEST);

	gl.disableVertexAttribArray(posLocation);
	gl.useProgram(0);
	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "clean");
}

void MultisampleTextureUsageCase::sampleTexture (tcu::Surface& dst, float value)
{
	static const tcu::Vec4 fullscreenQuad[] =
	{
		tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
		tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
	};

	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const int				posLocation			= gl.getAttribLocation(m_samplerShader->getProgram(), "a_position");
	const int				samplerLocation		= gl.getUniformLocation(m_samplerShader->getProgram(), "u_sampler");
	const int				maxSamplesLocation	= gl.getUniformLocation(m_samplerShader->getProgram(), "u_maxSamples");
	const int				layerLocation		= gl.getUniformLocation(m_samplerShader->getProgram(), "u_layer");
	const int				valueLocation		= gl.getUniformLocation(m_samplerShader->getProgram(), "u_cmpValue");
	const glw::GLenum		textureTarget		= (m_isArrayType) ? (GL_TEXTURE_2D_MULTISAMPLE_ARRAY) : (GL_TEXTURE_2D_MULTISAMPLE);
	glu::Buffer				vertexAttibBuffer	(m_context.getRenderContext());

	m_testCtx.getLog() << tcu::TestLog::Message << "Sampling from texture." << tcu::TestLog::EndMessage;

	// upload data

	gl.bindBuffer(GL_ARRAY_BUFFER, *vertexAttibBuffer);
	gl.bufferData(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), fullscreenQuad[0].getPtr(), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bufferdata");

	// clear

	gl.viewport(0, 0, s_textureSize, s_textureSize);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	// setup shader and draw

	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray(posLocation);

	gl.useProgram(m_samplerShader->getProgram());
	gl.uniform1i(samplerLocation, 0);
	gl.uniform1i(maxSamplesLocation, m_numSamples);
	if (m_isArrayType)
		gl.uniform1i(layerLocation, s_textureLayer);
	gl.uniform1f(valueLocation, value);
	gl.bindTexture(textureTarget, m_textureID);
	GLU_EXPECT_NO_ERROR(gl.getError(), "setup draw");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");

	// clean state

	gl.disableVertexAttribArray(posLocation);
	gl.useProgram(0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "clean");

	// read results
	gl.finish();
	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
}

bool MultisampleTextureUsageCase::verifyImage (const tcu::Surface& dst)
{
	bool error = false;

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying image." << tcu::TestLog::EndMessage;

	for (int y = 0; y < dst.getHeight(); ++y)
	for (int x = 0; x < dst.getWidth(); ++x)
	{
		const tcu::RGBA color				= dst.getPixel(x, y);
		const int		colorThresholdRed	= 1 << (8 - m_context.getRenderTarget().getPixelFormat().redBits);
		const int		colorThresholdGreen	= 1 << (8 - m_context.getRenderTarget().getPixelFormat().greenBits);
		const int		colorThresholdBlue	= 1 << (8 - m_context.getRenderTarget().getPixelFormat().blueBits);

		// only green is accepted
		if (color.getRed() > colorThresholdRed || color.getGreen() < 255 - colorThresholdGreen || color.getBlue() > colorThresholdBlue)
			error = true;
	}

	if (error)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixels found." << tcu::TestLog::EndMessage;
		m_testCtx.getLog()
			<< tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", dst)
			<< tcu::TestLog::EndImageSet;

		return false;
	}
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		return true;
	}
}

class NegativeFramebufferCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_DIFFERENT_N_SAMPLES_TEX = 0,
		CASE_DIFFERENT_N_SAMPLES_RBO,
		CASE_DIFFERENT_FIXED_TEX,
		CASE_DIFFERENT_FIXED_RBO,
		CASE_NON_ZERO_LEVEL,

		CASE_LAST
	};

						NegativeFramebufferCase		(Context& context, const char* name, const char* desc, CaseType caseType);
						~NegativeFramebufferCase	(void);

private:
	void				init						(void);
	void				deinit						(void);
	IterateResult		iterate						(void);

	void				getFormatSamples			(glw::GLenum target, std::vector<int>& samples);

	const CaseType		m_caseType;
	const int			m_fboSize;
	const glw::GLenum	m_internalFormat;

	int					m_numSamples0;	// !< samples for attachment 0
	int					m_numSamples1;	// !< samples for attachment 1
};

NegativeFramebufferCase::NegativeFramebufferCase (Context& context, const char* name, const char* desc, CaseType caseType)
	: TestCase			(context, name, desc)
	, m_caseType		(caseType)
	, m_fboSize			(64)
	, m_internalFormat	(GL_RGBA8)
	, m_numSamples0		(-1)
	, m_numSamples1		(-1)
{
}

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

void NegativeFramebufferCase::init (void)
{
	const bool				colorAttachmentTexture	= (m_caseType == CASE_DIFFERENT_N_SAMPLES_TEX) || (m_caseType == CASE_DIFFERENT_FIXED_TEX);
	const bool				colorAttachmentRbo		= (m_caseType == CASE_DIFFERENT_N_SAMPLES_RBO) || (m_caseType == CASE_DIFFERENT_FIXED_RBO);
	const bool				useDifferentSampleCounts= (m_caseType == CASE_DIFFERENT_N_SAMPLES_TEX) || (m_caseType == CASE_DIFFERENT_N_SAMPLES_RBO);
	std::vector<int>		textureSamples;
	std::vector<int>		rboSamples;

	getFormatSamples(GL_TEXTURE_2D_MULTISAMPLE, textureSamples);
	getFormatSamples(GL_RENDERBUFFER, rboSamples);

	TCU_CHECK(!textureSamples.empty());
	TCU_CHECK(!rboSamples.empty());

	// select sample counts

	if (useDifferentSampleCounts)
	{
		if (colorAttachmentTexture)
		{
			m_numSamples0 = textureSamples[0];

			if (textureSamples.size() >= 2)
				m_numSamples1 = textureSamples[1];
			else
				throw tcu::NotSupportedError("Test requires multiple supported sample counts");
		}
		else if (colorAttachmentRbo)
		{
			for (int texNdx = 0; texNdx < (int)textureSamples.size(); ++texNdx)
			for (int rboNdx = 0; rboNdx < (int)rboSamples.size(); ++rboNdx)
			{
				if (textureSamples[texNdx] != rboSamples[rboNdx])
				{
					m_numSamples0 = textureSamples[texNdx];
					m_numSamples1 = rboSamples[rboNdx];
					return;
				}
			}

			throw tcu::NotSupportedError("Test requires multiple supported sample counts");
		}
		else
			DE_ASSERT(DE_FALSE);
	}
	else
	{
		if (colorAttachmentTexture)
		{
			m_numSamples0 = textureSamples[0];
			m_numSamples1 = textureSamples[0];
		}
		else if (colorAttachmentRbo)
		{
			for (int texNdx = 0; texNdx < (int)textureSamples.size(); ++texNdx)
			for (int rboNdx = 0; rboNdx < (int)rboSamples.size(); ++rboNdx)
			{
				if (textureSamples[texNdx] == rboSamples[rboNdx])
				{
					m_numSamples0 = textureSamples[texNdx];
					m_numSamples1 = rboSamples[rboNdx];
					return;
				}
			}

			throw tcu::NotSupportedError("Test requires a sample count supported in both rbo and texture");
		}
		else
		{
			m_numSamples0 = textureSamples[0];
		}
	}
}

void NegativeFramebufferCase::deinit (void)
{
}

NegativeFramebufferCase::IterateResult NegativeFramebufferCase::iterate (void)
{
	const bool				colorAttachmentTexture	= (m_caseType == CASE_DIFFERENT_N_SAMPLES_TEX) || (m_caseType == CASE_DIFFERENT_FIXED_TEX);
	const bool				colorAttachmentRbo		= (m_caseType == CASE_DIFFERENT_N_SAMPLES_RBO) || (m_caseType == CASE_DIFFERENT_FIXED_RBO);
	const glw::GLboolean	fixedSampleLocations0	= (m_caseType == CASE_DIFFERENT_N_SAMPLES_RBO) ? (GL_TRUE) : (GL_FALSE);
	const glw::GLboolean	fixedSampleLocations1	= ((m_caseType == CASE_DIFFERENT_FIXED_TEX) || (m_caseType == CASE_DIFFERENT_FIXED_RBO)) ? (GL_TRUE) : (GL_FALSE);
	glu::CallLogWrapper		gl						(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	glw::GLuint				fboId					= 0;
	glw::GLuint				rboId					= 0;
	glw::GLuint				tex0Id					= 0;
	glw::GLuint				tex1Id					= 0;

	bool					testFailed				= false;

	gl.enableLogging(true);

	try
	{
		gl.glGenFramebuffers(1, &fboId);
		gl.glBindFramebuffer(GL_FRAMEBUFFER, fboId);
		GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen fbo");

		gl.glGenTextures(1, &tex0Id);
		gl.glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex0Id);
		gl.glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_numSamples0, m_internalFormat, m_fboSize, m_fboSize, fixedSampleLocations0);
		GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen texture 0");

		if (m_caseType == CASE_NON_ZERO_LEVEL)
		{
			glw::GLenum error;

			// attaching non-zero level generates invalid value
			gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex0Id, 5);
			error = gl.glGetError();

			if (error != GL_INVALID_VALUE)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Expected GL_INVALID_VALUE, got " << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
				testFailed = true;
			}
		}
		else
		{
			gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex0Id, 0);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "attach to c0");

			if (colorAttachmentTexture)
			{
				gl.glGenTextures(1, &tex1Id);
				gl.glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex1Id);
				gl.glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_numSamples1, m_internalFormat, m_fboSize, m_fboSize, fixedSampleLocations1);
				GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen texture 1");

				gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, tex1Id, 0);
				GLU_EXPECT_NO_ERROR(gl.glGetError(), "attach to c1");
			}
			else if (colorAttachmentRbo)
			{
				gl.glGenRenderbuffers(1, &rboId);
				gl.glBindRenderbuffer(GL_RENDERBUFFER, rboId);
				gl.glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples1, m_internalFormat, m_fboSize, m_fboSize);
				GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen rb");

				gl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rboId);
				GLU_EXPECT_NO_ERROR(gl.glGetError(), "attach to c1");
			}
			else
				DE_ASSERT(DE_FALSE);

			// should not be complete
			{
				glw::GLenum status = gl.glCheckFramebufferStatus(GL_FRAMEBUFFER);

				if (status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Expected GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, got " << glu::getFramebufferStatusName(status) << tcu::TestLog::EndMessage;
					testFailed = true;
				}
			}
		}
	}
	catch (...)
	{
		gl.glDeleteFramebuffers(1, &fboId);
		gl.glDeleteRenderbuffers(1, &rboId);
		gl.glDeleteTextures(1, &tex0Id);
		gl.glDeleteTextures(1, &tex1Id);
		throw;
	}

	gl.glDeleteFramebuffers(1, &fboId);
	gl.glDeleteRenderbuffers(1, &rboId);
	gl.glDeleteTextures(1, &tex0Id);
	gl.glDeleteTextures(1, &tex1Id);

	if (testFailed)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got wrong error code");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

void NegativeFramebufferCase::getFormatSamples (glw::GLenum target, std::vector<int>& samples)
{
	const glw::Functions	gl			= m_context.getRenderContext().getFunctions();
	int						sampleCount	= 0;

	gl.getInternalformativ(target, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCount);
	samples.resize(sampleCount);

	if (sampleCount > 0)
	{
		gl.getInternalformativ(target, m_internalFormat, GL_SAMPLES, sampleCount, &samples[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "get max samples");
	}
}

class NegativeTexParameterCase : public TestCase
{
public:
	enum TexParam
	{
		TEXTURE_MIN_FILTER = 0,
		TEXTURE_MAG_FILTER,
		TEXTURE_WRAP_S,
		TEXTURE_WRAP_T,
		TEXTURE_WRAP_R,
		TEXTURE_MIN_LOD,
		TEXTURE_MAX_LOD,
		TEXTURE_COMPARE_MODE,
		TEXTURE_COMPARE_FUNC,
		TEXTURE_BASE_LEVEL,

		TEXTURE_LAST
	};

					NegativeTexParameterCase	(Context& context, const char* name, const char* desc, TexParam param);
					~NegativeTexParameterCase	(void);

private:
	void			init						(void);
	void			deinit						(void);
	IterateResult	iterate						(void);

	glw::GLenum		getParamGLEnum				(void) const;
	glw::GLint		getParamValue				(void) const;
	glw::GLenum		getExpectedError			(void) const;

	const TexParam	m_texParam;
	int				m_iteration;
};

NegativeTexParameterCase::NegativeTexParameterCase (Context& context, const char* name, const char* desc, TexParam param)
	: TestCase		(context, name, desc)
	, m_texParam	(param)
	, m_iteration	(0)
{
	DE_ASSERT(param < TEXTURE_LAST);
}

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

void NegativeTexParameterCase::init (void)
{
	// default value
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}

void NegativeTexParameterCase::deinit (void)
{
}

NegativeTexParameterCase::IterateResult NegativeTexParameterCase::iterate (void)
{
	static const struct TextureType
	{
		const char*	name;
		glw::GLenum	target;
		glw::GLenum	internalFormat;
		bool		isArrayType;
	} types[] =
	{
		{ "color",					GL_TEXTURE_2D_MULTISAMPLE,			GL_RGBA8,	false	},
		{ "color array",			GL_TEXTURE_2D_MULTISAMPLE_ARRAY,	GL_RGBA8,	true	},
		{ "signed integer",			GL_TEXTURE_2D_MULTISAMPLE,			GL_R8I,		false	},
		{ "signed integer array",	GL_TEXTURE_2D_MULTISAMPLE_ARRAY,	GL_R8I,		true	},
		{ "unsigned integer",		GL_TEXTURE_2D_MULTISAMPLE,			GL_R8UI,	false	},
		{ "unsigned integer array",	GL_TEXTURE_2D_MULTISAMPLE_ARRAY,	GL_R8UI,	true	},
	};

	const tcu::ScopedLogSection scope(m_testCtx.getLog(), "Iteration", std::string() + "Testing parameter with " + types[m_iteration].name + " texture");
	const bool supportsES32orGL45 =
		glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
		glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));

	if (types[m_iteration].isArrayType && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
		m_testCtx.getLog() << tcu::TestLog::Message << "GL_OES_texture_storage_multisample_2d_array not supported, skipping target" << tcu::TestLog::EndMessage;
	else
	{
		glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
		glu::Texture			texture	(m_context.getRenderContext());
		glw::GLenum				error;

		gl.enableLogging(true);

		// gen texture

		gl.glBindTexture(types[m_iteration].target, *texture);

		if (types[m_iteration].isArrayType)
			gl.glTexStorage3DMultisample(types[m_iteration].target, 1, types[m_iteration].internalFormat, 16, 16, 16, GL_FALSE);
		else
			gl.glTexStorage2DMultisample(types[m_iteration].target, 1, types[m_iteration].internalFormat, 16, 16, GL_FALSE);
		GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup texture");

		// set param

		gl.glTexParameteri(types[m_iteration].target, getParamGLEnum(), getParamValue());
		error = gl.glGetError();

		// expect failure

		if (error != getExpectedError())
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Got unexpected error: " << glu::getErrorStr(error) << ", expected: " << glu::getErrorStr(getExpectedError()) << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got wrong error code");
		}
	}

	if (++m_iteration < DE_LENGTH_OF_ARRAY(types))
		return CONTINUE;
	return STOP;
}

glw::GLenum NegativeTexParameterCase::getParamGLEnum (void) const
{
	switch (m_texParam)
	{
		case TEXTURE_MIN_FILTER:	return GL_TEXTURE_MIN_FILTER;
		case TEXTURE_MAG_FILTER:	return GL_TEXTURE_MAG_FILTER;
		case TEXTURE_WRAP_S:		return GL_TEXTURE_WRAP_S;
		case TEXTURE_WRAP_T:		return GL_TEXTURE_WRAP_T;
		case TEXTURE_WRAP_R:		return GL_TEXTURE_WRAP_R;
		case TEXTURE_MIN_LOD:		return GL_TEXTURE_MIN_LOD;
		case TEXTURE_MAX_LOD:		return GL_TEXTURE_MAX_LOD;
		case TEXTURE_COMPARE_MODE:	return GL_TEXTURE_COMPARE_MODE;
		case TEXTURE_COMPARE_FUNC:	return GL_TEXTURE_COMPARE_FUNC;
		case TEXTURE_BASE_LEVEL:	return GL_TEXTURE_BASE_LEVEL;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

glw::GLint NegativeTexParameterCase::getParamValue (void) const
{
	switch (m_texParam)
	{
		case TEXTURE_MIN_FILTER:	return GL_LINEAR;
		case TEXTURE_MAG_FILTER:	return GL_LINEAR;
		case TEXTURE_WRAP_S:		return GL_CLAMP_TO_EDGE;
		case TEXTURE_WRAP_T:		return GL_CLAMP_TO_EDGE;
		case TEXTURE_WRAP_R:		return GL_CLAMP_TO_EDGE;
		case TEXTURE_MIN_LOD:		return 1;
		case TEXTURE_MAX_LOD:		return 5;
		case TEXTURE_COMPARE_MODE:	return GL_NONE;
		case TEXTURE_COMPARE_FUNC:	return GL_NOTEQUAL;
		case TEXTURE_BASE_LEVEL:	return 2;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

glw::GLenum NegativeTexParameterCase::getExpectedError (void) const
{
	switch (m_texParam)
	{
		case TEXTURE_MIN_FILTER:	return GL_INVALID_ENUM;
		case TEXTURE_MAG_FILTER:	return GL_INVALID_ENUM;
		case TEXTURE_WRAP_S:		return GL_INVALID_ENUM;
		case TEXTURE_WRAP_T:		return GL_INVALID_ENUM;
		case TEXTURE_WRAP_R:		return GL_INVALID_ENUM;
		case TEXTURE_MIN_LOD:		return GL_INVALID_ENUM;
		case TEXTURE_MAX_LOD:		return GL_INVALID_ENUM;
		case TEXTURE_COMPARE_MODE:	return GL_INVALID_ENUM;
		case TEXTURE_COMPARE_FUNC:	return GL_INVALID_ENUM;
		case TEXTURE_BASE_LEVEL:	return GL_INVALID_OPERATION;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

class NegativeTexureSampleCase : public TestCase
{
public:
	enum SampleCountParam
	{
		SAMPLECOUNT_HIGH = 0,
		SAMPLECOUNT_ZERO,

		SAMPLECOUNT_LAST
	};

							NegativeTexureSampleCase	(Context& context, const char* name, const char* desc, SampleCountParam param);
private:
	IterateResult			iterate						(void);

	const SampleCountParam	m_sampleParam;
};

NegativeTexureSampleCase::NegativeTexureSampleCase (Context& context, const char* name, const char* desc, SampleCountParam param)
	: TestCase		(context, name, desc)
	, m_sampleParam	(param)
{
	DE_ASSERT(param < SAMPLECOUNT_LAST);
}

NegativeTexureSampleCase::IterateResult NegativeTexureSampleCase::iterate (void)
{
	const glw::GLenum		expectedError	= (m_sampleParam == SAMPLECOUNT_HIGH) ? (GL_INVALID_OPERATION) : (GL_INVALID_VALUE);
	glu::CallLogWrapper		gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	glu::Texture			texture			(m_context.getRenderContext());
	glw::GLenum				error;
	int						samples			= -1;

	gl.enableLogging(true);

	// calc samples

	if (m_sampleParam == SAMPLECOUNT_HIGH)
	{
		int maxSamples = 0;

		gl.glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, 1, &maxSamples);
		GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetInternalformativ");

		samples = maxSamples + 1;
	}
	else if (m_sampleParam == SAMPLECOUNT_ZERO)
		samples = 0;
	else
		DE_ASSERT(DE_FALSE);

	// create texture with bad values

	gl.glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, *texture);
	gl.glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE);
	error = gl.glGetError();

	// expect failure

	if (error == expectedError)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got unexpected error: " << glu::getErrorStr(error) << ", expected: " << glu::getErrorStr(expectedError) << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got wrong error code");
	}

	return STOP;
}


} // anonymous

TextureMultisampleTests::TextureMultisampleTests (Context& context)
	: TestCaseGroup(context, "multisample", "Multisample texture tests")
{
}

TextureMultisampleTests::~TextureMultisampleTests (void)
{
}

void TextureMultisampleTests::init (void)
{
	static const int sampleCounts[] = { 1, 2, 3, 4, 8, 10, 12, 13, 16, 64 };

	static const struct TextureType
	{
		const char*									name;
		MultisampleTextureUsageCase::TextureType	type;
	} textureTypes[] =
	{
		{ "texture_color_2d",		MultisampleTextureUsageCase::TEXTURE_COLOR_2D		},
		{ "texture_color_2d_array",	MultisampleTextureUsageCase::TEXTURE_COLOR_2D_ARRAY	},
		{ "texture_int_2d",			MultisampleTextureUsageCase::TEXTURE_INT_2D			},
		{ "texture_int_2d_array",	MultisampleTextureUsageCase::TEXTURE_INT_2D_ARRAY	},
		{ "texture_uint_2d",		MultisampleTextureUsageCase::TEXTURE_UINT_2D		},
		{ "texture_uint_2d_array",	MultisampleTextureUsageCase::TEXTURE_UINT_2D_ARRAY	},
		{ "texture_depth_2d",		MultisampleTextureUsageCase::TEXTURE_DEPTH_2D		},
		{ "texture_depth_2d_array",	MultisampleTextureUsageCase::TEXTURE_DEPTH_2D_ARRAY	},
	};

	// .samples_x
	for (int sampleNdx = 0; sampleNdx < DE_LENGTH_OF_ARRAY(sampleCounts); ++sampleNdx)
	{
		tcu::TestCaseGroup* const sampleGroup = new tcu::TestCaseGroup(m_testCtx, (std::string("samples_") + de::toString(sampleCounts[sampleNdx])).c_str(), "Test with N samples");
		addChild(sampleGroup);

		// position query works
		sampleGroup->addChild(new SamplePosRasterizationTest(m_context, "sample_position", "test SAMPLE_POSITION", sampleCounts[sampleNdx]));

		// sample mask is ANDed properly
		sampleGroup->addChild(new SampleMaskCase(m_context, "sample_mask_only",											"Test with SampleMask only",									sampleCounts[sampleNdx],	SampleMaskCase::FLAGS_NONE));
		sampleGroup->addChild(new SampleMaskCase(m_context, "sample_mask_and_alpha_to_coverage",						"Test with SampleMask and alpha to coverage",					sampleCounts[sampleNdx],	SampleMaskCase::FLAGS_ALPHA_TO_COVERAGE));
		sampleGroup->addChild(new SampleMaskCase(m_context, "sample_mask_and_sample_coverage",							"Test with SampleMask and sample coverage",						sampleCounts[sampleNdx],	SampleMaskCase::FLAGS_SAMPLE_COVERAGE));
		sampleGroup->addChild(new SampleMaskCase(m_context, "sample_mask_and_sample_coverage_and_alpha_to_coverage",	"Test with SampleMask, sample coverage, and alpha to coverage",	sampleCounts[sampleNdx],	SampleMaskCase::FLAGS_ALPHA_TO_COVERAGE | SampleMaskCase::FLAGS_SAMPLE_COVERAGE));

		// high bits cause no unexpected behavior
		sampleGroup->addChild(new SampleMaskCase(m_context, "sample_mask_non_effective_bits",							"Test with SampleMask, set higher bits than sample count",		sampleCounts[sampleNdx],	SampleMaskCase::FLAGS_HIGH_BITS));

		// usage
		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(textureTypes); ++typeNdx)
			sampleGroup->addChild(new MultisampleTextureUsageCase(m_context, (std::string("use_") + textureTypes[typeNdx].name).c_str(), textureTypes[typeNdx].name, sampleCounts[sampleNdx], textureTypes[typeNdx].type));
	}

	// .negative
	{
		tcu::TestCaseGroup* const negativeGroup = new tcu::TestCaseGroup(m_testCtx, "negative", "Negative tests");
		addChild(negativeGroup);

		negativeGroup->addChild(new NegativeFramebufferCase	(m_context, "fbo_attach_different_sample_count_tex_tex",	"Attach different sample counts",	NegativeFramebufferCase::CASE_DIFFERENT_N_SAMPLES_TEX));
		negativeGroup->addChild(new NegativeFramebufferCase	(m_context, "fbo_attach_different_sample_count_tex_rbo",	"Attach different sample counts",	NegativeFramebufferCase::CASE_DIFFERENT_N_SAMPLES_RBO));
		negativeGroup->addChild(new NegativeFramebufferCase	(m_context, "fbo_attach_different_fixed_state_tex_tex",		"Attach fixed and non fixed",		NegativeFramebufferCase::CASE_DIFFERENT_FIXED_TEX));
		negativeGroup->addChild(new NegativeFramebufferCase	(m_context, "fbo_attach_different_fixed_state_tex_rbo",		"Attach fixed and non fixed",		NegativeFramebufferCase::CASE_DIFFERENT_FIXED_RBO));
		negativeGroup->addChild(new NegativeFramebufferCase	(m_context, "fbo_attach_non_zero_level",					"Attach non-zero level",			NegativeFramebufferCase::CASE_NON_ZERO_LEVEL));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_min_filter",							"set TEXTURE_MIN_FILTER",			NegativeTexParameterCase::TEXTURE_MIN_FILTER));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_mag_filter",							"set TEXTURE_MAG_FILTER",			NegativeTexParameterCase::TEXTURE_MAG_FILTER));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_wrap_s",								"set TEXTURE_WRAP_S",				NegativeTexParameterCase::TEXTURE_WRAP_S));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_wrap_t",								"set TEXTURE_WRAP_T",				NegativeTexParameterCase::TEXTURE_WRAP_T));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_wrap_r",								"set TEXTURE_WRAP_R",				NegativeTexParameterCase::TEXTURE_WRAP_R));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_min_lod",								"set TEXTURE_MIN_LOD",				NegativeTexParameterCase::TEXTURE_MIN_LOD));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_max_lod",								"set TEXTURE_MAX_LOD",				NegativeTexParameterCase::TEXTURE_MAX_LOD));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_compare_mode",							"set TEXTURE_COMPARE_MODE",			NegativeTexParameterCase::TEXTURE_COMPARE_MODE));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_compare_func",							"set TEXTURE_COMPARE_FUNC",			NegativeTexParameterCase::TEXTURE_COMPARE_FUNC));
		negativeGroup->addChild(new NegativeTexParameterCase(m_context, "texture_base_level",							"set TEXTURE_BASE_LEVEL",			NegativeTexParameterCase::TEXTURE_BASE_LEVEL));
		negativeGroup->addChild(new NegativeTexureSampleCase(m_context, "texture_high_sample_count",					"TexStorage with high numSamples",	NegativeTexureSampleCase::SAMPLECOUNT_HIGH));
		negativeGroup->addChild(new NegativeTexureSampleCase(m_context, "texture_zero_sample_count",					"TexStorage with zero numSamples",	NegativeTexureSampleCase::SAMPLECOUNT_ZERO));
	}
}

} // Functional
} // gles31
} // deqp
