/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2015 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 Primitive bounding box tests.
 *//*--------------------------------------------------------------------*/

#include "es31fPrimitiveBoundingBoxTests.hpp"

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

#include <vector>
#include <sstream>
#include <algorithm>

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

namespace StateQueryUtil = ::deqp::gls::StateQueryUtil;

struct BoundingBox
{
	tcu::Vec4 min;
	tcu::Vec4 max;

	/*--------------------------------------------------------------------*//*!
	 * Get component by index of a 8-component vector constructed by
	 * concatenating 4-component min and max vectors.
	 *//*--------------------------------------------------------------------*/
	float&			getComponentAccess	(int ndx);
	const float&	getComponentAccess	(int ndx) const;
};

float& BoundingBox::getComponentAccess (int ndx)
{
	DE_ASSERT(ndx >= 0 && ndx < 8);
	if (ndx < 4)
		return min[ndx];
	else
		return max[ndx-4];
}

const float& BoundingBox::getComponentAccess (int ndx) const
{
	return const_cast<BoundingBox*>(this)->getComponentAccess(ndx);
}

struct ProjectedBBox
{
	tcu::Vec3	min;
	tcu::Vec3	max;
};

static ProjectedBBox projectBoundingBox (const BoundingBox& bbox)
{
	const float		wMin	= de::max(0.0f, bbox.min.w()); // clamp to w=0 as extension requires
	const float		wMax	= de::max(0.0f, bbox.max.w());
	ProjectedBBox	retVal;

	retVal.min = tcu::min(bbox.min.swizzle(0, 1, 2) / wMin,
						  bbox.min.swizzle(0, 1, 2) / wMax);
	retVal.max = tcu::max(bbox.max.swizzle(0, 1, 2) / wMin,
						  bbox.max.swizzle(0, 1, 2) / wMax);
	return retVal;
}

static tcu::IVec4 getViewportBoundingBoxArea (const ProjectedBBox& bbox, const tcu::IVec2& viewportSize, float size = 0.0f)
{
	tcu::Vec4	vertexBox;
	tcu::IVec4	pixelBox;

	vertexBox.x() = (bbox.min.x() * 0.5f + 0.5f) * (float)viewportSize.x();
	vertexBox.y() = (bbox.min.y() * 0.5f + 0.5f) * (float)viewportSize.y();
	vertexBox.z() = (bbox.max.x() * 0.5f + 0.5f) * (float)viewportSize.x();
	vertexBox.w() = (bbox.max.y() * 0.5f + 0.5f) * (float)viewportSize.y();

	pixelBox.x() = deFloorFloatToInt32(vertexBox.x() - size/2.0f);
	pixelBox.y() = deFloorFloatToInt32(vertexBox.y() - size/2.0f);
	pixelBox.z() = deCeilFloatToInt32(vertexBox.z() + size/2.0f);
	pixelBox.w() = deCeilFloatToInt32(vertexBox.w() + size/2.0f);
	return pixelBox;
}

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

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

	if (glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
	{
		specializationMap["ARB_ES32_COMPATIBILITY_REQUIRE"] = "";
		specializationMap["GEOMETRY_SHADER_REQUIRE"] = "";
		specializationMap["GEOMETRY_POINT_SIZE"] = "#extension GL_EXT_geometry_point_size : require";
		specializationMap["GPU_SHADER5_REQUIRE"] = "";
		specializationMap["TESSELLATION_SHADER_REQUIRE"] = "";
		specializationMap["TESSELLATION_POINT_SIZE_REQUIRE"] = "#extension GL_EXT_tessellation_point_size : require";
		specializationMap["PRIMITIVE_BOUNDING_BOX_REQUIRE"] = "";
		specializationMap["PRIM_GL_BOUNDING_BOX"] = "gl_BoundingBox";
	}
	else if (glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
	{
		specializationMap["ARB_ES32_COMPATIBILITY_REQUIRE"] = "#extension GL_ARB_ES3_2_compatibility : require";
		specializationMap["GEOMETRY_SHADER_REQUIRE"] = "";
		specializationMap["GEOMETRY_POINT_SIZE"] = "";
		specializationMap["GPU_SHADER5_REQUIRE"] = "";
		specializationMap["TESSELLATION_SHADER_REQUIRE"] = "";
		specializationMap["TESSELLATION_POINT_SIZE_REQUIRE"] = "";
		specializationMap["PRIMITIVE_BOUNDING_BOX_REQUIRE"] = "";
		specializationMap["PRIM_GL_BOUNDING_BOX"] = "gl_BoundingBox";
	}
	else
	{
		specializationMap["ARB_ES32_COMPATIBILITY_REQUIRE"] = "";
		specializationMap["GEOMETRY_SHADER_REQUIRE"] = "#extension GL_EXT_geometry_shader : require";
		specializationMap["GEOMETRY_POINT_SIZE"] = "#extension GL_EXT_geometry_point_size : require";
		specializationMap["GPU_SHADER5_REQUIRE"] = "#extension GL_EXT_gpu_shader5 : require";
		specializationMap["TESSELLATION_SHADER_REQUIRE"] = "#extension GL_EXT_tessellation_shader : require";
		specializationMap["TESSELLATION_POINT_SIZE_REQUIRE"] = "#extension GL_EXT_tessellation_point_size : require";
		specializationMap["PRIMITIVE_BOUNDING_BOX_REQUIRE"] = "#extension GL_EXT_primitive_bounding_box : require";
		specializationMap["PRIM_GL_BOUNDING_BOX"] = "gl_BoundingBoxEXT";
	}

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

static decltype(glw::Functions::primitiveBoundingBox)
getBoundingBoxFunction(Context& context)
{
	decltype(glw::Functions::primitiveBoundingBox) boundingBoxFunc;
	const glw::Functions& funcs = context.getRenderContext().getFunctions();

	/* OpenGL ES is assumed to have it (extensions checks passed). */
	if (glu::isContextTypeES(context.getRenderContext().getType()))
		return funcs.primitiveBoundingBox;

	boundingBoxFunc = (decltype(boundingBoxFunc))
		context.getRenderContext().getProcAddress("glPrimitiveBoundingBoxARB");

	DE_ASSERT(boundingBoxFunc);

	return boundingBoxFunc;
}

static bool supportsES32OrGL45(Context& context)
{
	return glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
	       glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5));
}

static bool boundingBoxSupported(Context& context)
{
   /* Require one of:
    *    - OpenGL ES 3.2
    *    - OpenGL 4.5 + GL_ARB_ES3_2_compatibility
    *    - OpenGL ES 3.1 + GL_EXT_primitive_bounding_box
    */
   return glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
	  ((glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5)) &&
	   context.getContextInfo().isExtensionSupported("GL_ARB_ES3_2_compatibility")) ||
	  context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"));
}

class InitialValueCase : public TestCase
{
public:
					InitialValueCase	(Context& context, const char* name, const char* desc);

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

InitialValueCase::InitialValueCase (Context& context, const char* name, const char* desc)
	: TestCase(context, name, desc)
{
}

void InitialValueCase::init (void)
{
	if (!boundingBoxSupported(m_context))
		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
}

InitialValueCase::IterateResult InitialValueCase::iterate (void)
{
	StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat[8]>	state;
	glu::CallLogWrapper											gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	gl.enableLogging(true);

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Querying GL_PRIMITIVE_BOUNDING_BOX_EXT, expecting (-1, -1, -1, 1) (1, 1, 1, 1)"
		<< tcu::TestLog::EndMessage;

	gl.glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");

	if (!state.verifyValidity(m_testCtx))
		return STOP;

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Got " << tcu::formatArray(&state[0], &state[8])
		<< tcu::TestLog::EndMessage;

	if ((state[0] != -1.0f) || (state[1] != -1.0f) || (state[2] != -1.0f) || (state[3] != 1.0f) ||
		(state[4] !=  1.0f) || (state[5] !=  1.0f) || (state[6] !=  1.0f) || (state[7] != 1.0f))
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Error, unexpected value"
			<< tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid initial value");
	}
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	return STOP;
}

class QueryCase : public TestCase
{
public:
	enum QueryMethod
	{
		QUERY_FLOAT = 0,
		QUERY_BOOLEAN,
		QUERY_INT,
		QUERY_INT64,

		QUERY_LAST
	};

						QueryCase	(Context& context, const char* name, const char* desc, QueryMethod method);

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

	bool				verifyState	(glu::CallLogWrapper& gl, const BoundingBox& bbox) const;

	const QueryMethod	m_method;
};

QueryCase::QueryCase (Context& context, const char* name, const char* desc, QueryMethod method)
	: TestCase	(context, name, desc)
	, m_method	(method)
{
	DE_ASSERT(method < QUERY_LAST);
}

void QueryCase::init (void)
{
	if (!boundingBoxSupported(m_context))
		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
}

QueryCase::IterateResult QueryCase::iterate (void)
{
	static const BoundingBox fixedCases[] =
	{
		{ tcu::Vec4( 0.0f,  0.0f,  0.0f,  0.0f), tcu::Vec4( 0.0f,  0.0f,  0.0f,  0.0f) },
		{ tcu::Vec4(-0.0f, -0.0f, -0.0f, -0.0f), tcu::Vec4( 0.0f,  0.0f,  0.0f, -0.0f) },
		{ tcu::Vec4( 0.0f,  0.0f,  0.0f,  0.0f), tcu::Vec4( 1.0f,  1.0f,  1.0f, -1.0f) },
		{ tcu::Vec4( 2.0f,  2.0f,  2.0f,  2.0f), tcu::Vec4( 1.5f,  1.5f,  1.5f,  1.0f) },
		{ tcu::Vec4( 1.0f,  1.0f,  1.0f,  1.0f), tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f) },
		{ tcu::Vec4( 1.0f,  1.0f,  1.0f,  0.3f), tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.2f) },
	};

	const int					numRandomCases	= 9;
	glu::CallLogWrapper			gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	de::Random					rnd				(0xDE3210);
	std::vector<BoundingBox>	cases;

	cases.insert(cases.begin(), DE_ARRAY_BEGIN(fixedCases), DE_ARRAY_END(fixedCases));
	for (int ndx = 0; ndx < numRandomCases; ++ndx)
	{
		BoundingBox	boundingBox;

		// parameter evaluation order is not guaranteed, cannot just do "max = (rand(), rand(), ...)
		for (int coordNdx = 0; coordNdx < 8; ++coordNdx)
			boundingBox.getComponentAccess(coordNdx) = rnd.getFloat(-4.0f, 4.0f);

		cases.push_back(boundingBox);
	}

	gl.enableLogging(true);
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	auto boundingBoxFunc = getBoundingBoxFunction(m_context);

	for (int caseNdx = 0; caseNdx < (int)cases.size(); ++caseNdx)
	{
		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Iteration", "Iteration " + de::toString(caseNdx+1));
		const BoundingBox&			boundingBox	= cases[caseNdx];

		/* On desktop GL, we cannot use call wrapper here but must use resolved extension function. */
		if (!glu::isContextTypeES(m_context.getRenderContext().getType())) {
			boundingBoxFunc(boundingBox.min.x(), boundingBox.min.y(), boundingBox.min.z(), boundingBox.min.w(),
					boundingBox.max.x(), boundingBox.max.y(), boundingBox.max.z(), boundingBox.max.w());
		}
		else {
			gl.glPrimitiveBoundingBox(boundingBox.min.x(), boundingBox.min.y(), boundingBox.min.z(), boundingBox.min.w(),
						  boundingBox.max.x(), boundingBox.max.y(), boundingBox.max.z(), boundingBox.max.w());
		}

		if (!verifyState(gl, boundingBox))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected query result");
	}

	return STOP;
}

bool QueryCase::verifyState (glu::CallLogWrapper& gl, const BoundingBox& bbox) const
{
	switch (m_method)
	{
		case QUERY_FLOAT:
		{
			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat[8]>	state;
			bool														error = false;

			gl.glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");

			if (!state.verifyValidity(m_testCtx))
				return false;

			m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "glGetFloatv returned " << tcu::formatArray(&state[0], &state[8])
					<< tcu::TestLog::EndMessage;

			for (int ndx = 0; ndx < 8; ++ndx)
				if (state[ndx] != bbox.getComponentAccess(ndx))
					error = true;

			if (error)
			{
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "Error, unexpected value\n"
					<< "Expected ["
					<< bbox.min.x() << ", " << bbox.min.y() << ", " << bbox.min.z() << ", " << bbox.min.w() << ", "
					<< bbox.max.x() << ", " << bbox.max.y() << ", " << bbox.max.z() << ", " << bbox.max.w() << "]"
					<< tcu::TestLog::EndMessage;
				return false;
			}
			return true;
		}

		case QUERY_INT:
		{
			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[8]>	state;
			bool														error = false;

			gl.glGetIntegerv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");

			if (!state.verifyValidity(m_testCtx))
				return false;

			m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "glGetIntegerv returned " << tcu::formatArray(&state[0], &state[8])
					<< tcu::TestLog::EndMessage;

			for (int ndx = 0; ndx < 8; ++ndx)
				if (state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint>(bbox.getComponentAccess(ndx)) &&
					state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint>(bbox.getComponentAccess(ndx)))
					error = true;

			if (error)
			{
				tcu::MessageBuilder builder(&m_testCtx.getLog());

				builder	<< "Error, unexpected value\n"
						<< "Expected [";

				for (int ndx = 0; ndx < 8; ++ndx)
				{
					const glw::GLint roundDown	= StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint>(bbox.getComponentAccess(ndx));
					const glw::GLint roundUp	= StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint>(bbox.getComponentAccess(ndx));

					if (ndx != 0)
						builder << ", ";

					if (roundDown == roundUp)
						builder << roundDown;
					else
						builder << "{" << roundDown << ", " << roundUp << "}";
				}

				builder	<< "]"
						<< tcu::TestLog::EndMessage;
				return false;
			}
			return true;
		}

		case QUERY_INT64:
		{
			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint64[8]>	state;
			bool																error = false;

			gl.glGetInteger64v(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");

			if (!state.verifyValidity(m_testCtx))
				return false;

			m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "glGetInteger64v returned " << tcu::formatArray(&state[0], &state[8])
					<< tcu::TestLog::EndMessage;

			for (int ndx = 0; ndx < 8; ++ndx)
				if (state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(bbox.getComponentAccess(ndx)) &&
					state[ndx] != StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(bbox.getComponentAccess(ndx)))
					error = true;

			if (error)
			{
				tcu::MessageBuilder builder(&m_testCtx.getLog());

				builder	<< "Error, unexpected value\n"
						<< "Expected [";

				for (int ndx = 0; ndx < 8; ++ndx)
				{
					const glw::GLint64 roundDown	= StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(bbox.getComponentAccess(ndx));
					const glw::GLint64 roundUp		= StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(bbox.getComponentAccess(ndx));

					if (ndx != 0)
						builder << ", ";

					if (roundDown == roundUp)
						builder << roundDown;
					else
						builder << "{" << roundDown << ", " << roundUp << "}";
				}

				builder	<< "]"
						<< tcu::TestLog::EndMessage;
				return false;
			}
			return true;
		}

		case QUERY_BOOLEAN:
		{
			StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean[8]>	state;
			bool															error = false;

			gl.glGetBooleanv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");

			if (!state.verifyValidity(m_testCtx))
				return false;

			m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "glGetBooleanv returned ["
					<< glu::getBooleanStr(state[0]) << ", " << glu::getBooleanStr(state[1]) << ", " << glu::getBooleanStr(state[2]) << ", " << glu::getBooleanStr(state[3]) << ", "
					<< glu::getBooleanStr(state[4]) << ", " << glu::getBooleanStr(state[5]) << ", " << glu::getBooleanStr(state[6]) << ", " << glu::getBooleanStr(state[7]) << "]\n"
					<< tcu::TestLog::EndMessage;

			for (int ndx = 0; ndx < 8; ++ndx)
				if (state[ndx] != ((bbox.getComponentAccess(ndx) != 0.0f) ? (GL_TRUE) : (GL_FALSE)))
					error = true;

			if (error)
			{
				tcu::MessageBuilder builder(&m_testCtx.getLog());

				builder	<< "Error, unexpected value\n"
						<< "Expected [";

				for (int ndx = 0; ndx < 8; ++ndx)
				{
					if (ndx != 0)
						builder << ", ";

					builder << ((bbox.getComponentAccess(ndx) != 0.0f) ? ("GL_TRUE") : ("GL_FALSE"));
				}

				builder	<< "]"
						<< tcu::TestLog::EndMessage;
				return false;
			}
			return true;
		}

		default:
			DE_ASSERT(false);
			return true;
	}
}

class BBoxRenderCase : public TestCase
{
public:
	enum
	{
		FLAG_RENDERTARGET_DEFAULT	= 1u << 0, //!< render to default renderbuffer
		FLAG_RENDERTARGET_FBO		= 1u << 1, //!< render to framebuffer object

		FLAG_BBOXSIZE_EQUAL			= 1u << 2, //!< set tight primitive bounding box
		FLAG_BBOXSIZE_LARGER		= 1u << 3, //!< set padded primitive bounding box
		FLAG_BBOXSIZE_SMALLER		= 1u << 4, //!< set too small primitive bounding box

		FLAG_TESSELLATION			= 1u << 5, //!< use tessellation shader
		FLAG_GEOMETRY				= 1u << 6, //!< use geometry shader

		FLAG_SET_BBOX_STATE			= 1u << 7, //!< set primitive bounding box using global state
		FLAG_SET_BBOX_OUTPUT		= 1u << 8, //!< set primitive bounding box using tessellation output
		FLAG_PER_PRIMITIVE_BBOX		= 1u << 9, //!< set primitive bounding per primitive

		FLAGBIT_USER_BIT			= 10u //!< bits N and and up are reserved for subclasses
	};

									BBoxRenderCase					(Context& context, const char* name, const char* description, int numIterations, deUint32 flags);
									~BBoxRenderCase					(void);

protected:
	enum RenderTarget
	{
		RENDERTARGET_DEFAULT,
		RENDERTARGET_FBO,
	};
	enum BBoxSize
	{
		BBOXSIZE_EQUAL,
		BBOXSIZE_LARGER,
		BBOXSIZE_SMALLER,
	};

	enum
	{
		RENDER_TARGET_MIN_SIZE	= 256,
		FBO_SIZE				= 512,
		MIN_VIEWPORT_SIZE		= 256,
		MAX_VIEWPORT_SIZE		= 512,
	};
	DE_STATIC_ASSERT(MIN_VIEWPORT_SIZE <= RENDER_TARGET_MIN_SIZE);

	enum
	{
		VA_POS_VEC_NDX		= 0,
		VA_COL_VEC_NDX		= 1,
		VA_NUM_ATTRIB_VECS	= 2,
	};

	enum AABBRoundDirection
	{
		ROUND_INWARDS = 0,
		ROUND_OUTWARDS
	};

	struct IterationConfig
	{
		tcu::IVec2	viewportPos;
		tcu::IVec2	viewportSize;
		tcu::Vec2	patternPos;		//!< in NDC
		tcu::Vec2	patternSize;	//!< in NDC
		BoundingBox	bbox;
	};

	virtual void					init							(void);
	virtual void					deinit							(void);
	IterateResult					iterate							(void);

	virtual std::string				genVertexSource					(void) const = 0;
	virtual std::string				genFragmentSource				(void) const = 0;
	virtual std::string				genTessellationControlSource	(void) const = 0;
	virtual std::string				genTessellationEvaluationSource	(void) const = 0;
	virtual std::string				genGeometrySource				(void) const = 0;

	virtual IterationConfig			generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const = 0;
	virtual void					getAttributeData				(std::vector<tcu::Vec4>& data) const = 0;
	virtual void					renderTestPattern				(const IterationConfig& config) = 0;
	virtual void					verifyRenderResult				(const IterationConfig& config) = 0;

	IterationConfig					generateRandomConfig			(int seed, const tcu::IVec2& renderTargetSize) const;
	tcu::IVec4						getViewportPatternArea			(const tcu::Vec2& patternPos, const tcu::Vec2& patternSize, const tcu::IVec2& viewportSize, AABBRoundDirection roundDir) const;

	void							setupRender						(const IterationConfig& config);

	enum ShaderFunction
	{
		SHADER_FUNC_MIRROR_X,
		SHADER_FUNC_MIRROR_Y,
		SHADER_FUNC_INSIDE_BBOX,
	};

	const char*						genShaderFunction				(ShaderFunction func) const;

	const RenderTarget				m_renderTarget;
	const BBoxSize					m_bboxSize;
	const bool						m_hasTessellationStage;
	const bool						m_hasGeometryStage;
	const bool						m_useGlobalState;
	const bool						m_calcPerPrimitiveBBox;
	const int						m_numIterations;

	de::MovePtr<glu::ShaderProgram>	m_program;
	de::MovePtr<glu::Buffer>		m_vbo;
	de::MovePtr<glu::Framebuffer>	m_fbo;
	glw::GLuint			m_vao;

	decltype(glw::Functions::primitiveBoundingBox)	m_boundingBoxFunc;

private:
	std::vector<IterationConfig>	m_iterationConfigs;
	int								m_iteration;
};

BBoxRenderCase::BBoxRenderCase (Context& context, const char* name, const char* description, int numIterations, deUint32 flags)
	: TestCase					(context, name, description)
	, m_renderTarget			((flags & FLAG_RENDERTARGET_DEFAULT) ? (RENDERTARGET_DEFAULT) : (RENDERTARGET_FBO))
	, m_bboxSize				((flags & FLAG_BBOXSIZE_EQUAL) ? (BBOXSIZE_EQUAL) : (flags & FLAG_BBOXSIZE_SMALLER) ? (BBOXSIZE_SMALLER) : (BBOXSIZE_LARGER))
	, m_hasTessellationStage	((flags & FLAG_TESSELLATION) != 0)
	, m_hasGeometryStage		((flags & FLAG_GEOMETRY) != 0)
	, m_useGlobalState			((flags & FLAG_SET_BBOX_STATE) != 0)
	, m_calcPerPrimitiveBBox	((flags & FLAG_PER_PRIMITIVE_BBOX) != 0)
	, m_numIterations			(numIterations)
	, m_vao					(0)
	, m_boundingBoxFunc			(NULL)
	, m_iteration				(0)
{
	// validate flags
	DE_ASSERT((((m_renderTarget == RENDERTARGET_DEFAULT)	?	(FLAG_RENDERTARGET_DEFAULT)	: (0)) |
			   ((m_renderTarget == RENDERTARGET_FBO)		?	(FLAG_RENDERTARGET_FBO)		: (0)) |
			   ((m_bboxSize == BBOXSIZE_EQUAL)				?	(FLAG_BBOXSIZE_EQUAL)		: (0)) |
			   ((m_bboxSize == BBOXSIZE_LARGER)				?	(FLAG_BBOXSIZE_LARGER)		: (0)) |
			   ((m_bboxSize == BBOXSIZE_SMALLER)			?	(FLAG_BBOXSIZE_SMALLER)		: (0)) |
			   ((m_hasTessellationStage)					?	(FLAG_TESSELLATION)			: (0)) |
			   ((m_hasGeometryStage)						?	(FLAG_GEOMETRY)				: (0)) |
			   ((m_useGlobalState)							?	(FLAG_SET_BBOX_STATE)		: (0)) |
			   ((!m_useGlobalState)							?	(FLAG_SET_BBOX_OUTPUT)		: (0)) |
			   ((m_calcPerPrimitiveBBox)					?	(FLAG_PER_PRIMITIVE_BBOX)	: (0))) == (flags & ((1u << FLAGBIT_USER_BIT) - 1)));

	DE_ASSERT(m_useGlobalState || m_hasTessellationStage); // using non-global state requires tessellation

	if (m_calcPerPrimitiveBBox)
	{
		DE_ASSERT(!m_useGlobalState); // per-primitive test requires per-primitive (non-global) state
		DE_ASSERT(m_bboxSize == BBOXSIZE_EQUAL); // smaller is hard to verify, larger not interesting
	}
}

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

void BBoxRenderCase::init (void)
{
	const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
	const tcu::IVec2		renderTargetSize	= (m_renderTarget == RENDERTARGET_DEFAULT) ?
													(tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) :
													(tcu::IVec2(FBO_SIZE, FBO_SIZE));
	const bool			hasES32OrGL45		= supportsES32OrGL45(m_context);

	// requirements
	if (!boundingBoxSupported(m_context))
		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
	if (!hasES32OrGL45 && m_hasTessellationStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	if (!hasES32OrGL45 && m_hasGeometryStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
	if (m_renderTarget == RENDERTARGET_DEFAULT && (renderTargetSize.x() < RENDER_TARGET_MIN_SIZE || renderTargetSize.y() < RENDER_TARGET_MIN_SIZE))
		throw tcu::NotSupportedError(std::string() + "Test requires " + de::toString<int>(RENDER_TARGET_MIN_SIZE) + "x" + de::toString<int>(RENDER_TARGET_MIN_SIZE) + " default framebuffer");

	// log case specifics
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Setting primitive bounding box "
			<< ((m_calcPerPrimitiveBBox)         ? ("to exactly cover each generated primitive")
			  : (m_bboxSize == BBOXSIZE_EQUAL)   ? ("to exactly cover rendered grid")
			  : (m_bboxSize == BBOXSIZE_LARGER)  ? ("to cover the grid and include some padding")
			  : (m_bboxSize == BBOXSIZE_SMALLER) ? ("to cover only a subset of the grid")
			  : (DE_NULL))
			<< ".\n"
		<< "Rendering with vertex"
			<< ((m_hasTessellationStage) ? ("-tessellation{ctrl,eval}") : (""))
			<< ((m_hasGeometryStage) ? ("-geometry") : (""))
			<< "-fragment program.\n"
		<< "Set bounding box using "
			<< ((m_useGlobalState) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
			<< "\n"
		<< "Verifying rendering results are valid within the bounding box."
		<< tcu::TestLog::EndMessage;

	// resources

	{
		glu::ProgramSources sources;
		sources << glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()));
		sources << glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()));

		if (m_hasTessellationStage)
			sources << glu::TessellationControlSource(specializeShader(m_context, genTessellationControlSource().c_str()))
					<< glu::TessellationEvaluationSource(specializeShader(m_context, genTessellationEvaluationSource().c_str()));
		if (m_hasGeometryStage)
			sources << glu::GeometrySource(specializeShader(m_context, genGeometrySource().c_str()));

		m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources));
		GLU_EXPECT_NO_ERROR(gl.getError(), "build program");

		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "ShaderProgram", "Shader program");
			m_testCtx.getLog() << *m_program;
		}

		if (!m_program->isOk())
			throw tcu::TestError("failed to build program");
	}

	if (m_renderTarget == RENDERTARGET_FBO)
	{
		glu::Texture colorAttachment(m_context.getRenderContext());

		gl.bindTexture(GL_TEXTURE_2D, *colorAttachment);
		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, FBO_SIZE, FBO_SIZE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");

		m_fbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, **m_fbo);
		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *colorAttachment, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "attach");

		// unbind to prevent texture name deletion from removing it from current fbo attachments
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
	}

	m_boundingBoxFunc = getBoundingBoxFunction(m_context);

	{
		std::vector<tcu::Vec4> data;

		getAttributeData(data);

		// Generate VAO for desktop OpenGL
		if (!glu::isContextTypeES(m_context.getRenderContext().getType())) {
			gl.genVertexArrays(1, &m_vao);
			gl.bindVertexArray(m_vao);
		}

		m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
		gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
		gl.bufferData(GL_ARRAY_BUFFER, (int)(data.size() * sizeof(tcu::Vec4)), &data[0], GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "create vbo");
	}

	// Iterations
	for (int iterationNdx = 0; iterationNdx < m_numIterations; ++iterationNdx)
		m_iterationConfigs.push_back(generateConfig(iterationNdx, renderTargetSize));
}

void BBoxRenderCase::deinit (void)
{
	m_program.clear();
	m_vbo.clear();
	m_fbo.clear();

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

BBoxRenderCase::IterateResult BBoxRenderCase::iterate (void)
{
	const tcu::ScopedLogSection	section		(m_testCtx.getLog(),
											 std::string() + "Iteration" + de::toString((int)m_iteration),
											 std::string() + "Iteration " + de::toString((int)m_iteration+1) + "/" + de::toString((int)m_iterationConfigs.size()));
	const IterationConfig&		config		= m_iterationConfigs[m_iteration];

	// default
	if (m_iteration == 0)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	renderTestPattern(config);
	verifyRenderResult(config);

	if (++m_iteration < (int)m_iterationConfigs.size())
		return CONTINUE;

	return STOP;
}

BBoxRenderCase::IterationConfig BBoxRenderCase::generateRandomConfig (int seed, const tcu::IVec2& renderTargetSize) const
{
	de::Random		rnd		(seed);
	IterationConfig	config;

	// viewport config
	config.viewportSize.x()	= rnd.getInt(MIN_VIEWPORT_SIZE, de::min<int>(renderTargetSize.x(), MAX_VIEWPORT_SIZE));
	config.viewportSize.y()	= rnd.getInt(MIN_VIEWPORT_SIZE, de::min<int>(renderTargetSize.y(), MAX_VIEWPORT_SIZE));
	config.viewportPos.x()	= rnd.getInt(0, renderTargetSize.x() - config.viewportSize.x());
	config.viewportPos.y()	= rnd.getInt(0, renderTargetSize.y() - config.viewportSize.y());

	// pattern location inside viewport
	config.patternSize.x()	= rnd.getFloat(0.4f, 1.4f);
	config.patternSize.y()	= rnd.getFloat(0.4f, 1.4f);
	config.patternPos.x()	= rnd.getFloat(-1.0f, 1.0f - config.patternSize.x());
	config.patternPos.y()	= rnd.getFloat(-1.0f, 1.0f - config.patternSize.y());

	// accurate bounding box
	config.bbox.min			= tcu::Vec4(config.patternPos.x(), config.patternPos.y(), 0.0f, 1.0f);
	config.bbox.max			= tcu::Vec4(config.patternPos.x() + config.patternSize.x(), config.patternPos.y() + config.patternSize.y(), 0.0f, 1.0f);

	if (m_bboxSize == BBOXSIZE_LARGER)
	{
		// increase bbox size
		config.bbox.min.x() -= rnd.getFloat() * 0.5f;
		config.bbox.min.y() -= rnd.getFloat() * 0.5f;
		config.bbox.min.z() -= rnd.getFloat() * 0.5f;

		config.bbox.max.x() += rnd.getFloat() * 0.5f;
		config.bbox.max.y() += rnd.getFloat() * 0.5f;
		config.bbox.max.z() += rnd.getFloat() * 0.5f;
	}
	else if (m_bboxSize == BBOXSIZE_SMALLER)
	{
		// reduce bbox size
		config.bbox.min.x() += rnd.getFloat() * 0.4f * config.patternSize.x();
		config.bbox.min.y() += rnd.getFloat() * 0.4f * config.patternSize.y();

		config.bbox.max.x() -= rnd.getFloat() * 0.4f * config.patternSize.x();
		config.bbox.max.y() -= rnd.getFloat() * 0.4f * config.patternSize.y();
	}

	return config;
}

tcu::IVec4 BBoxRenderCase::getViewportPatternArea (const tcu::Vec2& patternPos, const tcu::Vec2& patternSize, const tcu::IVec2& viewportSize, AABBRoundDirection roundDir) const
{
	const float	halfPixel	= 0.5f;
	tcu::Vec4	vertexBox;
	tcu::IVec4	pixelBox;

	vertexBox.x() = (patternPos.x() * 0.5f + 0.5f) * (float)viewportSize.x();
	vertexBox.y() = (patternPos.y() * 0.5f + 0.5f) * (float)viewportSize.y();
	vertexBox.z() = ((patternPos.x() + patternSize.x()) * 0.5f + 0.5f) * (float)viewportSize.x();
	vertexBox.w() = ((patternPos.y() + patternSize.y()) * 0.5f + 0.5f) * (float)viewportSize.y();

	if (roundDir == ROUND_INWARDS)
	{
		pixelBox.x() = (int)deFloatCeil(vertexBox.x()+halfPixel);
		pixelBox.y() = (int)deFloatCeil(vertexBox.y()+halfPixel);
		pixelBox.z() = (int)deFloatFloor(vertexBox.z()-halfPixel);
		pixelBox.w() = (int)deFloatFloor(vertexBox.w()-halfPixel);
	}
	else
	{
		pixelBox.x() = (int)deFloatFloor(vertexBox.x()-halfPixel);
		pixelBox.y() = (int)deFloatFloor(vertexBox.y()-halfPixel);
		pixelBox.z() = (int)deFloatCeil(vertexBox.z()+halfPixel);
		pixelBox.w() = (int)deFloatCeil(vertexBox.w()+halfPixel);
	}

	return pixelBox;
}

void BBoxRenderCase::setupRender (const IterationConfig& config)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const glw::GLint		posLocation			= gl.getAttribLocation(m_program->getProgram(), "a_position");
	const glw::GLint		colLocation			= gl.getAttribLocation(m_program->getProgram(), "a_color");
	const glw::GLint		posScaleLocation	= gl.getUniformLocation(m_program->getProgram(), "u_posScale");

	TCU_CHECK(posLocation != -1);
	TCU_CHECK(colLocation != -1);
	TCU_CHECK(posScaleLocation != -1);

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Setting viewport to ("
			<< "x: " << config.viewportPos.x() << ", "
			<< "y: " << config.viewportPos.y() << ", "
			<< "w: " << config.viewportSize.x() << ", "
			<< "h: " << config.viewportSize.y() << ")\n"
		<< "Vertex coordinates are in range:\n"
			<< "\tx: [" << config.patternPos.x() << ", " << (config.patternPos.x() + config.patternSize.x()) << "]\n"
			<< "\ty: [" << config.patternPos.y() << ", " << (config.patternPos.y() + config.patternSize.y()) << "]\n"
		<< tcu::TestLog::EndMessage;

	if (!m_calcPerPrimitiveBBox)
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Setting primitive bounding box to:\n"
				<< "\t" << config.bbox.min << "\n"
				<< "\t" << config.bbox.max << "\n"
			<< tcu::TestLog::EndMessage;

	if (m_useGlobalState)
		m_boundingBoxFunc(config.bbox.min.x(), config.bbox.min.y(), config.bbox.min.z(), config.bbox.min.w(),
				  config.bbox.max.x(), config.bbox.max.y(), config.bbox.max.z(), config.bbox.max.w());
	else
		// state is overriden by the tessellation output, set bbox to invisible area to imitiate dirty state left by application
		m_boundingBoxFunc(-2.0f, -2.0f, 0.0f, 1.0f, -1.7f, -1.7f, 0.0f, 1.0f);

	if (m_fbo)
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, **m_fbo);

	gl.viewport(config.viewportPos.x(), config.viewportPos.y(), config.viewportSize.x(), config.viewportSize.y());
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);

	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, (int)(VA_NUM_ATTRIB_VECS * sizeof(float[4])), glu::BufferOffsetAsPointer(4 * VA_POS_VEC_NDX * sizeof(float)));
	gl.vertexAttribPointer(colLocation, 4, GL_FLOAT, GL_FALSE, (int)(VA_NUM_ATTRIB_VECS * sizeof(float[4])), glu::BufferOffsetAsPointer(4 * VA_COL_VEC_NDX * sizeof(float)));
	gl.enableVertexAttribArray(posLocation);
	gl.enableVertexAttribArray(colLocation);
	gl.useProgram(m_program->getProgram());
	gl.uniform4f(posScaleLocation, config.patternPos.x(), config.patternPos.y(), config.patternSize.x(), config.patternSize.y());

	{
		const glw::GLint bboxMinPos = gl.getUniformLocation(m_program->getProgram(), "u_primitiveBBoxMin");
		const glw::GLint bboxMaxPos = gl.getUniformLocation(m_program->getProgram(), "u_primitiveBBoxMax");

		gl.uniform4f(bboxMinPos, config.bbox.min.x(), config.bbox.min.y(), config.bbox.min.z(), config.bbox.min.w());
		gl.uniform4f(bboxMaxPos, config.bbox.max.x(), config.bbox.max.y(), config.bbox.max.z(), config.bbox.max.w());
	}

	gl.uniform2i(gl.getUniformLocation(m_program->getProgram(), "u_viewportPos"), config.viewportPos.x(), config.viewportPos.y());
	gl.uniform2i(gl.getUniformLocation(m_program->getProgram(), "u_viewportSize"), config.viewportSize.x(), config.viewportSize.y());

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

const char* BBoxRenderCase::genShaderFunction (ShaderFunction func) const
{
	switch (func)
	{
		case SHADER_FUNC_MIRROR_X:
			return	"vec4 mirrorX(in highp vec4 p)\n"
					"{\n"
					"	highp vec2 patternOffset = u_posScale.xy;\n"
					"	highp vec2 patternScale = u_posScale.zw;\n"
					"	highp vec2 patternCenter = patternOffset + patternScale * 0.5;\n"
					"	return vec4(2.0 * patternCenter.x - p.x, p.y, p.z, p.w);\n"
					"}\n";

		case SHADER_FUNC_MIRROR_Y:
			return	"vec4 mirrorY(in highp vec4 p)\n"
					"{\n"
					"	highp vec2 patternOffset = u_posScale.xy;\n"
					"	highp vec2 patternScale = u_posScale.zw;\n"
					"	highp vec2 patternCenter = patternOffset + patternScale * 0.5;\n"
					"	return vec4(p.x, 2.0 * patternCenter.y - p.y, p.z, p.w);\n"
					"}\n";

		case SHADER_FUNC_INSIDE_BBOX:
			return	"uniform highp ivec2 u_viewportPos;\n"
					"uniform highp ivec2 u_viewportSize;\n"
					"flat in highp float v_bbox_expansionSize;\n"
					"flat in highp vec3 v_bbox_clipMin;\n"
					"flat in highp vec3 v_bbox_clipMax;\n"
					"\n"
					"bool fragmentInsideTheBBox(in highp float depth)\n"
					"{\n"
					"	highp vec4 wc = vec4(floor((v_bbox_clipMin.x * 0.5 + 0.5) * float(u_viewportSize.x) - v_bbox_expansionSize/2.0),\n"
					"	                     floor((v_bbox_clipMin.y * 0.5 + 0.5) * float(u_viewportSize.y) - v_bbox_expansionSize/2.0),\n"
					"	                     ceil((v_bbox_clipMax.x * 0.5 + 0.5) * float(u_viewportSize.x) + v_bbox_expansionSize/2.0),\n"
					"	                     ceil((v_bbox_clipMax.y * 0.5 + 0.5) * float(u_viewportSize.y) + v_bbox_expansionSize/2.0));\n"
					"	if (gl_FragCoord.x < float(u_viewportPos.x) + wc.x || gl_FragCoord.x > float(u_viewportPos.x) + wc.z ||\n"
					"	    gl_FragCoord.y < float(u_viewportPos.y) + wc.y || gl_FragCoord.y > float(u_viewportPos.y) + wc.w)\n"
					"	    return false;\n"
					"	const highp float dEpsilon = 0.001;\n"
					"	if (depth*2.0-1.0 < v_bbox_clipMin.z - dEpsilon || depth*2.0-1.0 > v_bbox_clipMax.z + dEpsilon)\n"
					"	    return false;\n"
					"	return true;\n"
					"}\n";
		default:
			DE_ASSERT(false);
			return "";
	}
}

class GridRenderCase : public BBoxRenderCase
{
public:
					GridRenderCase					(Context& context, const char* name, const char* description, deUint32 flags);
					~GridRenderCase					(void);

private:
	void			init							(void);

	std::string		genVertexSource					(void) const;
	std::string		genFragmentSource				(void) const;
	std::string		genTessellationControlSource	(void) const;
	std::string		genTessellationEvaluationSource	(void) const;
	std::string		genGeometrySource				(void) const;

	IterationConfig	generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const;
	void			getAttributeData				(std::vector<tcu::Vec4>& data) const;
	void			renderTestPattern				(const IterationConfig& config);
	void			verifyRenderResult				(const IterationConfig& config);

	const int		m_gridSize;
};

GridRenderCase::GridRenderCase (Context& context, const char* name, const char* description, deUint32 flags)
	: BBoxRenderCase	(context, name, description, 12, flags)
	, m_gridSize		(24)
{
}

GridRenderCase::~GridRenderCase (void)
{
}

void GridRenderCase::init (void)
{
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Rendering yellow-green grid to " << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
		<< "Grid cells are in random order, varying grid size and location for each iteration.\n"
		<< "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated blue channel."
		<< tcu::TestLog::EndMessage;

	BBoxRenderCase::init();
}

std::string GridRenderCase::genVertexSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in highp vec4 a_position;\n"
			"in highp vec4 a_color;\n"
			"out highp vec4 vtx_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"\n";
	if (!m_hasTessellationStage)
	{
		DE_ASSERT(m_useGlobalState);
		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
				"uniform highp vec4 u_primitiveBBoxMax;\n"
				"\n"
				"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
				"\n";
	}

	buf <<	"void main()\n"
			"{\n"
			"	highp vec2 patternOffset = u_posScale.xy;\n"
			"	highp vec2 patternScale = u_posScale.zw;\n"
			"	gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
			"	vtx_color = a_color;\n";

	if (!m_hasTessellationStage)
	{
		DE_ASSERT(m_useGlobalState);
		buf <<	"\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = 0.0;\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin =\n"
				"	    min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMin.w,\n"
				"	        vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMax.w);\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax =\n"
				"	    min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMin.w,\n"
				"	        vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMax.w);\n";
	}

	buf<<	"}\n";

	return buf.str();
}

std::string GridRenderCase::genFragmentSource (void) const
{
	const char* const	colorInputName = (m_hasGeometryStage) ? ("geo_color") : (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in mediump vec4 " << colorInputName << ";\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
		<<	genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
		<<	"\n"
			"void main()\n"
			"{\n"
			"	mediump vec4 baseColor = " << colorInputName << ";\n"
			"	mediump float blueChannel;\n"
			"	if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
			"		blueChannel = 0.0;\n"
			"	else\n"
			"		blueChannel = 1.0;\n"
			"	o_color = vec4(baseColor.r, baseColor.g, blueChannel, baseColor.a);\n"
			"}\n";

	return buf.str();
}

std::string GridRenderCase::genTessellationControlSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
			"layout(vertices=3) out;\n"
			"\n"
			"in highp vec4 vtx_color[];\n"
			"out highp vec4 tess_ctrl_color[];\n"
			"uniform highp float u_tessellationLevel;\n"
			"uniform highp vec4 u_posScale;\n";

	if (!m_calcPerPrimitiveBBox)
	{
		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
				"uniform highp vec4 u_primitiveBBoxMax;\n";
	}

	buf <<	"patch out highp float vp_bbox_expansionSize;\n"
			"patch out highp vec3 vp_bbox_clipMin;\n"
			"patch out highp vec3 vp_bbox_clipMax;\n";

	if (m_calcPerPrimitiveBBox)
	{
		buf <<	"\n";
		if (m_hasGeometryStage)
			buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
		buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);

		buf <<	"vec4 transformVec(in highp vec4 p)\n"
				"{\n"
				"	return " << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)")) << ";\n"
				"}\n";
	}

	buf <<	"\n"
			"void main()\n"
			"{\n"
			"	// convert to nonsensical coordinates, just in case\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
			"	tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
			"\n"
			"	gl_TessLevelOuter[0] = u_tessellationLevel;\n"
			"	gl_TessLevelOuter[1] = u_tessellationLevel;\n"
			"	gl_TessLevelOuter[2] = u_tessellationLevel;\n"
			"	gl_TessLevelInner[0] = u_tessellationLevel;\n";

	if (m_calcPerPrimitiveBBox)
	{
		buf <<	"\n"
				"	highp vec4 bboxMin = min(min(transformVec(gl_in[0].gl_Position),\n"
				"	                             transformVec(gl_in[1].gl_Position)),\n"
				"	                         transformVec(gl_in[2].gl_Position));\n"
				"	highp vec4 bboxMax = max(max(transformVec(gl_in[0].gl_Position),\n"
				"	                             transformVec(gl_in[1].gl_Position)),\n"
				"	                         transformVec(gl_in[2].gl_Position));\n";
	}
	else
	{
		buf <<	"\n"
				"	highp vec4 bboxMin = u_primitiveBBoxMin;\n"
				"	highp vec4 bboxMax = u_primitiveBBoxMax;\n";
	}

	if (!m_useGlobalState)
		buf <<	"\n"
				"	${PRIM_GL_BOUNDING_BOX}[0] = bboxMin;\n"
				"	${PRIM_GL_BOUNDING_BOX}[1] = bboxMax;\n";

	buf <<	"	vp_bbox_expansionSize = 0.0;\n"
			"	vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
			"	                      vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
			"	vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
			"	                      vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
			"}\n";

	return buf.str();
}

std::string GridRenderCase::genTessellationEvaluationSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"${GPU_SHADER5_REQUIRE}\n"
			"layout(triangles) in;\n"
			"\n"
			"in highp vec4 tess_ctrl_color[];\n"
			"out highp vec4 tess_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"patch in highp float vp_bbox_expansionSize;\n"
			"patch in highp vec3 vp_bbox_clipMin;\n"
			"patch in highp vec3 vp_bbox_clipMax;\n"
			"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
			"\n"
			"precise gl_Position;\n"
			"\n"
		<<	genShaderFunction(SHADER_FUNC_MIRROR_Y)
		<<	"void main()\n"
			"{\n"
			"	// non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
			"	gl_Position = mirrorY(gl_TessCoord.x * gl_in[0].gl_Position.zwyx +\n"
			"	                      gl_TessCoord.y * gl_in[1].gl_Position.zwyx +\n"
			"	                      gl_TessCoord.z * gl_in[2].gl_Position.zwyx);\n"
			"	tess_color = tess_ctrl_color[0];\n"
			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = vp_bbox_expansionSize;\n"
			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin = vp_bbox_clipMin;\n"
			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax = vp_bbox_clipMax;\n"
			"}\n";

	return buf.str();
}

std::string GridRenderCase::genGeometrySource (void) const
{
	const char* const	colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GEOMETRY_SHADER_REQUIRE}\n"
			"layout(triangles) in;\n"
			"layout(max_vertices=9, triangle_strip) out;\n"
			"\n"
			"in highp vec4 " << colorInputName << "[3];\n"
			"out highp vec4 geo_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"\n"
			"flat in highp float v_geo_bbox_expansionSize[3];\n"
			"flat in highp vec3 v_geo_bbox_clipMin[3];\n"
			"flat in highp vec3 v_geo_bbox_clipMax[3];\n"
			"flat out highp vec3 v_bbox_clipMin;\n"
			"flat out highp vec3 v_bbox_clipMax;\n"
			"flat out highp float v_bbox_expansionSize;\n"
		<<	genShaderFunction(SHADER_FUNC_MIRROR_X)
		<<	"\n"
			"void setVisualizationVaryings()\n"
			"{\n"
			"	v_bbox_expansionSize = v_geo_bbox_expansionSize[0];\n"
			"	v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
			"	v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
			"}\n"
			"void main()\n"
			"{\n"
			"	// Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
			"	highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
			"	highp vec4 p1 = mirrorX(gl_in[1].gl_Position);\n"
			"	highp vec4 p2 = mirrorX(gl_in[2].gl_Position);\n"
			"	highp vec4 pCentroid = vec4((p0.xyz + p1.xyz + p2.xyz) / 3.0, 1.0);\n"
			"	highp vec4 triangleColor = " << colorInputName << "[0];\n"
			"\n"
			"	gl_Position = p0; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = p1; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	EndPrimitive();\n"
			"\n"
			"	gl_Position = p1; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = p2; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	EndPrimitive();\n"
			"\n"
			"	gl_Position = p2; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = p0; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
			"	EndPrimitive();\n"
			"}\n";

	return buf.str();
}

GridRenderCase::IterationConfig GridRenderCase::generateConfig (int iteration, const tcu::IVec2& renderTargetSize) const
{
	return generateRandomConfig(0xDEDEDEu * (deUint32)iteration, renderTargetSize);
}

void GridRenderCase::getAttributeData (std::vector<tcu::Vec4>& data) const
{
	const tcu::Vec4		green				(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4		yellow				(1.0f, 1.0f, 0.0f, 1.0f);
	std::vector<int>	cellOrder			(m_gridSize * m_gridSize);
	de::Random			rnd					(0xDE56789);

	// generate grid with cells in random order
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
		cellOrder[ndx] = ndx;
	rnd.shuffle(cellOrder.begin(), cellOrder.end());

	data.resize(m_gridSize * m_gridSize * 6 * 2);
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
	{
		const int			cellNdx		= cellOrder[ndx];
		const int			cellX		= cellNdx % m_gridSize;
		const int			cellY		= cellNdx / m_gridSize;
		const tcu::Vec4&	cellColor	= ((cellX+cellY)%2 == 0) ? (green) : (yellow);

		data[(ndx * 6 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+0) / float(m_gridSize), float(cellY+0) / float(m_gridSize), 0.0f, 1.0f);
		data[(ndx * 6 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
		data[(ndx * 6 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+1) / float(m_gridSize), float(cellY+1) / float(m_gridSize), 0.0f, 1.0f);
		data[(ndx * 6 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
		data[(ndx * 6 + 2) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+0) / float(m_gridSize), float(cellY+1) / float(m_gridSize), 0.0f, 1.0f);
		data[(ndx * 6 + 2) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
		data[(ndx * 6 + 3) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+0) / float(m_gridSize), float(cellY+0) / float(m_gridSize), 0.0f, 1.0f);
		data[(ndx * 6 + 3) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
		data[(ndx * 6 + 4) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+1) / float(m_gridSize), float(cellY+0) / float(m_gridSize), 0.0f, 1.0f);
		data[(ndx * 6 + 4) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
		data[(ndx * 6 + 5) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(cellX+1) / float(m_gridSize), float(cellY+1) / float(m_gridSize), 0.0f, 1.0f);
		data[(ndx * 6 + 5) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
	}
}

void GridRenderCase::renderTestPattern (const IterationConfig& config)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	setupRender(config);

	if (m_hasTessellationStage)
	{
		const glw::GLint	tessLevelPos	= gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
		const glw::GLfloat	tessLevel		= 2.8f; // will be rounded up

		TCU_CHECK(tessLevelPos != -1);

		m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel << tcu::TestLog::EndMessage;

		gl.uniform1f(tessLevelPos, tessLevel);
		gl.patchParameteri(GL_PATCH_VERTICES, 3);
		GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
	}

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

	gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_TRIANGLES), 0, m_gridSize * m_gridSize * 6);
	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
}

void GridRenderCase::verifyRenderResult (const IterationConfig& config)
{
	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
	const ProjectedBBox		projectedBBox			= projectBoundingBox(config.bbox);
	const tcu::IVec4		viewportBBoxArea		= getViewportBoundingBoxArea(projectedBBox, config.viewportSize);
	const tcu::IVec4		viewportGridOuterArea	= getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_OUTWARDS);
	const tcu::IVec4		viewportGridInnerArea	= getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
	tcu::Surface			viewportSurface			(config.viewportSize.x(), config.viewportSize.y());
	tcu::Surface			errorMask				(config.viewportSize.x(), config.viewportSize.y());
	bool					anyError				= false;

	if (!m_calcPerPrimitiveBBox)
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Projected bounding box: (clip space)\n"
				<< "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
				<< "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
				<< "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
			<< "In viewport coordinates:\n"
				<< "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
				<< "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
			<< "Verifying render results within the bounding box.\n"
			<< tcu::TestLog::EndMessage;
	else
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying render result."
			<< tcu::TestLog::EndMessage;

	if (m_fbo)
		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
	glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(), viewportSurface.getAccess());

	tcu::clear(errorMask.getAccess(), tcu::IVec4(0,0,0,255));

	for (int y = de::max(viewportBBoxArea.y(), 0); y < de::min(viewportBBoxArea.w(), config.viewportSize.y()); ++y)
	for (int x = de::max(viewportBBoxArea.x(), 0); x < de::min(viewportBBoxArea.z(), config.viewportSize.x()); ++x)
	{
		const tcu::RGBA	pixel		= viewportSurface.getPixel(x, y);
		const bool		outsideGrid	= x < viewportGridOuterArea.x() ||
									  y < viewportGridOuterArea.y() ||
									  x > viewportGridOuterArea.z() ||
									  y > viewportGridOuterArea.w();
		const bool		insideGrid	= x > viewportGridInnerArea.x() &&
									  y > viewportGridInnerArea.y() &&
									  x < viewportGridInnerArea.z() &&
									  y < viewportGridInnerArea.w();

		bool			error		= false;

		if (outsideGrid)
		{
			// expect black
			if (pixel.getRed() != 0 || pixel.getGreen() != 0 || pixel.getBlue() != 0)
				error = true;
		}

		else if (insideGrid)
		{
			// expect green, yellow or a combination of these
			if (pixel.getGreen() != 255 || pixel.getBlue() != 0)
				error = true;
		}
		else
		{
			// boundary, allow anything
		}

		if (error)
		{
			errorMask.setPixel(x, y, tcu::RGBA::red());
			anyError = true;
		}
	}

	if (anyError)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
			<< tcu::TestLog::EndImageSet;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Result image ok."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
			<< tcu::TestLog::EndImageSet;
	}
}

class LineRenderCase : public BBoxRenderCase
{
public:
	enum
	{
		LINEFLAG_WIDE = 1u << FLAGBIT_USER_BIT,	//!< use wide lines
	};

					LineRenderCase					(Context& context, const char* name, const char* description, deUint32 flags);
					~LineRenderCase					(void);

private:
	enum
	{
		GREEN_COMPONENT_NDX = 1,
		BLUE_COMPONENT_NDX = 2,

		SCAN_ROW_COMPONENT_NDX = GREEN_COMPONENT_NDX, // \note: scans are orthogonal to the line
		SCAN_COL_COMPONENT_NDX = BLUE_COMPONENT_NDX,
	};

	enum QueryDirection
	{
		DIRECTION_HORIZONTAL = 0,
		DIRECTION_VERTICAL,
	};

	enum ScanResult
	{
		SCANRESULT_NUM_LINES_OK_BIT		= (1 << 0),
		SCANRESULT_LINE_WIDTH_OK_BIT	= (1 << 1),
		SCANRESULT_LINE_WIDTH_WARN_BIT	= (1 << 2),
		SCANRESULT_LINE_WIDTH_ERR_BIT	= (1 << 3),
		SCANRESULT_LINE_CONT_OK_BIT		= (1 << 4),
		SCANRESULT_LINE_CONT_ERR_BIT	= (1 << 5),
		SCANRESULT_LINE_CONT_WARN_BIT	= (1 << 6),
	};

	void				init							(void);

	std::string			genVertexSource					(void) const;
	std::string			genFragmentSource				(void) const;
	std::string			genTessellationControlSource	(void) const;
	std::string			genTessellationEvaluationSource	(void) const;
	std::string			genGeometrySource				(void) const;

	IterationConfig		generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const;
	void				getAttributeData				(std::vector<tcu::Vec4>& data) const;
	void				renderTestPattern				(const IterationConfig& config);
	void				verifyRenderResult				(const IterationConfig& config);

	tcu::IVec2			getNumberOfLinesRange			(int queryAreaBegin, int queryAreaEnd, float patternStart, float patternSize, int viewportArea, QueryDirection queryDir) const;
	deUint8				scanRow							(const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, int rowViewportBegin, int rowViewportEnd, const tcu::IVec2& numLines, int& floodCounter) const;
	deUint8				scanColumn						(const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, int columnViewportBegin, int columnViewportEnd, const tcu::IVec2& numLines, int& floodCounter) const;
	bool				checkAreaNumLines				(const tcu::ConstPixelBufferAccess& access, const tcu::IVec4& area, int& floodCounter, int componentNdx, const tcu::IVec2& numLines) const;
	deUint8				checkLineContinuity				(const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const;
	tcu::IVec2			getNumMinimaMaxima				(const tcu::ConstPixelBufferAccess& access, int componentNdx) const;
	deUint8				checkLineWidths					(const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& floodCounter) const;
	void				printLineWidthError				(const tcu::IVec2& pos, int detectedLineWidth, const tcu::IVec2& lineWidthRange, bool isHorizontal, int& floodCounter) const;

	const int			m_patternSide;
	const bool			m_isWideLineCase;
	const int			m_wideLineLineWidth;
};

LineRenderCase::LineRenderCase (Context& context, const char* name, const char* description, deUint32 flags)
	: BBoxRenderCase		(context, name, description, 12, flags)
	, m_patternSide			(12)
	, m_isWideLineCase		((flags & LINEFLAG_WIDE) != 0)
	, m_wideLineLineWidth	(5)
{
}

LineRenderCase::~LineRenderCase (void)
{
}

void LineRenderCase::init (void)
{
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Rendering line pattern to " << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
		<< "Vertical lines are green, horizontal lines blue. Using additive blending.\n"
		<< "Line segments are in random order, varying pattern size and location for each iteration.\n"
		<< "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated red channel."
		<< tcu::TestLog::EndMessage;

	if (m_isWideLineCase)
	{
		glw::GLfloat lineWidthRange[2] = {0.0f, 0.0f};
		m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);

		if (lineWidthRange[1] < (float)m_wideLineLineWidth)
			throw tcu::NotSupportedError("Test requires line width " + de::toString(m_wideLineLineWidth));
	}

	BBoxRenderCase::init();
}

std::string LineRenderCase::genVertexSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in highp vec4 a_position;\n"
			"in highp vec4 a_color;\n"
			"out highp vec4 vtx_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"uniform highp float u_lineWidth;\n"
			"\n";
	if (!m_hasTessellationStage)
	{
		DE_ASSERT(m_useGlobalState);
		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
				"uniform highp vec4 u_primitiveBBoxMax;\n"
				"\n"
				"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
				"\n";
	}
	buf <<	"void main()\n"
			"{\n"
			"	highp vec2 patternOffset = u_posScale.xy;\n"
			"	highp vec2 patternScale = u_posScale.zw;\n"
			"	gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
			"	vtx_color = a_color;\n";
	if (!m_hasTessellationStage)
	{
		DE_ASSERT(m_useGlobalState);
		buf <<	"\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = u_lineWidth;\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin =\n"
				"	    min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMin.w,\n"
				"	        vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMax.w);\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax =\n"
				"	    min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMin.w,\n"
				"	        vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMax.w);\n";
	}
	buf <<	"}\n";

	return buf.str();
}

std::string LineRenderCase::genFragmentSource (void) const
{
	const char* const	colorInputName = (m_hasGeometryStage) ? ("geo_color") : (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in mediump vec4 " << colorInputName << ";\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
		<<	genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
		<<	"\n"
			"void main()\n"
			"{\n"
			"	mediump vec4 baseColor = " << colorInputName << ";\n"
			"	mediump float redChannel;\n"
			"	if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
			"		redChannel = 0.0;\n"
			"	else\n"
			"		redChannel = 1.0;\n"
			"	o_color = vec4(redChannel, baseColor.g, baseColor.b, baseColor.a);\n"
			"}\n";

	return buf.str();
}

std::string LineRenderCase::genTessellationControlSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
			"layout(vertices=2) out;"
			"\n"
			"in highp vec4 vtx_color[];\n"
			"out highp vec4 tess_ctrl_color[];\n"
			"uniform highp float u_tessellationLevel;\n"
			"uniform highp vec4 u_posScale;\n"
			"uniform highp float u_lineWidth;\n";

	if (!m_calcPerPrimitiveBBox)
	{
		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
				"uniform highp vec4 u_primitiveBBoxMax;\n";
	}

	buf <<	"patch out highp float vp_bbox_expansionSize;\n"
			"patch out highp vec3 vp_bbox_clipMin;\n"
			"patch out highp vec3 vp_bbox_clipMax;\n";

	if (m_calcPerPrimitiveBBox)
	{
		buf <<	"\n";
		if (m_hasGeometryStage)
			buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
		buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);

		buf <<	"vec4 transformVec(in highp vec4 p)\n"
				"{\n"
				"	return " << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)")) << ";\n"
				"}\n";
	}

	buf <<	"\n"
			"void main()\n"
			"{\n"
			"	// convert to nonsensical coordinates, just in case\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
			"	tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
			"\n"
			"	gl_TessLevelOuter[0] = 0.8; // will be rounded up to 1\n"
			"	gl_TessLevelOuter[1] = u_tessellationLevel;\n";

	if (m_calcPerPrimitiveBBox)
	{
		buf <<	"\n"
				"	highp vec4 bboxMin = min(transformVec(gl_in[0].gl_Position),\n"
				"	                         transformVec(gl_in[1].gl_Position));\n"
				"	highp vec4 bboxMax = max(transformVec(gl_in[0].gl_Position),\n"
				"	                         transformVec(gl_in[1].gl_Position));\n";
	}
	else
	{
		buf <<	"\n"
				"	highp vec4 bboxMin = u_primitiveBBoxMin;\n"
				"	highp vec4 bboxMax = u_primitiveBBoxMax;\n";
	}

	if (!m_useGlobalState)
		buf <<	"\n"
				"	${PRIM_GL_BOUNDING_BOX}[0] = bboxMin;\n"
				"	${PRIM_GL_BOUNDING_BOX}[1] = bboxMax;\n";

	buf <<	"	vp_bbox_expansionSize = u_lineWidth;\n"
			"	vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
			"	                      vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
			"	vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
			"	                      vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
			"}\n";

	return buf.str();
}

std::string LineRenderCase::genTessellationEvaluationSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"layout(isolines) in;"
			"\n"
			"in highp vec4 tess_ctrl_color[];\n"
			"out highp vec4 tess_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"\n"
			"patch in highp float vp_bbox_expansionSize;\n"
			"patch in highp vec3 vp_bbox_clipMin;\n"
			"patch in highp vec3 vp_bbox_clipMax;\n"
			"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
		<<	genShaderFunction(SHADER_FUNC_MIRROR_Y)
		<<	"void main()\n"
			"{\n"
			"	// non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
			"	gl_Position = mirrorY(mix(gl_in[0].gl_Position.zwyx, gl_in[1].gl_Position.zwyx, gl_TessCoord.x));\n"
			"	tess_color = tess_ctrl_color[0];\n"
			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = vp_bbox_expansionSize;\n"
			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin = vp_bbox_clipMin;\n"
			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax = vp_bbox_clipMax;\n"
			"}\n";

	return buf.str();
}

std::string LineRenderCase::genGeometrySource (void) const
{
	const char* const	colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GEOMETRY_SHADER_REQUIRE}\n"
			"layout(lines) in;\n"
			"layout(max_vertices=5, line_strip) out;\n"
			"\n"
			"in highp vec4 " << colorInputName << "[2];\n"
			"out highp vec4 geo_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"\n"
			"\n"
			"flat in highp float v_geo_bbox_expansionSize[2];\n"
			"flat in highp vec3 v_geo_bbox_clipMin[2];\n"
			"flat in highp vec3 v_geo_bbox_clipMax[2];\n"
			"flat out highp vec3 v_bbox_clipMin;\n"
			"flat out highp vec3 v_bbox_clipMax;\n"
			"flat out highp float v_bbox_expansionSize;\n"
		<<	genShaderFunction(SHADER_FUNC_MIRROR_X)
		<<	"\n"
			"void setVisualizationVaryings()\n"
			"{\n"
			"	v_bbox_expansionSize = v_geo_bbox_expansionSize[0];\n"
			"	v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
			"	v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
			"}\n"
			"void main()\n"
			"{\n"
			"	// Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
			"	highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
			"	highp vec4 p1 = mirrorX(gl_in[1].gl_Position);\n"
			"	highp vec4 lineColor = " << colorInputName << "[0];\n"
			"\n"
			"	// output two separate primitives, just in case\n"
			"	gl_Position = mix(p0, p1, 0.00); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = mix(p0, p1, 0.33); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
			"	EndPrimitive();\n"
			"\n"
			"	gl_Position = mix(p0, p1, 0.33); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = mix(p0, p1, 0.67); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
			"	gl_Position = mix(p0, p1, 1.00); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
			"	EndPrimitive();\n"
			"}\n";

	return buf.str();
}

LineRenderCase::IterationConfig LineRenderCase::generateConfig (int iteration, const tcu::IVec2& renderTargetSize) const
{
	const int numMaxAttempts = 128;

	// Avoid too narrow viewports, lines could merge together. Require viewport is at least 2.5x the size of the line bodies.
	for (int attemptNdx = 0; attemptNdx < numMaxAttempts; ++attemptNdx)
	{
		const IterationConfig& config = generateRandomConfig((0xDEDEDEu * (deUint32)iteration) ^ (0xABAB13 * attemptNdx), renderTargetSize);

		if ((float)config.viewportSize.x() * (config.patternSize.x() * 0.5f) > 2.5f * (float)m_patternSide * (float)m_wideLineLineWidth &&
			(float)config.viewportSize.y() * (config.patternSize.y() * 0.5f) > 2.5f * (float)m_patternSide * (float)m_wideLineLineWidth)
		{
			return config;
		}
	}

	DE_ASSERT(false);
	return IterationConfig();
}

void LineRenderCase::getAttributeData (std::vector<tcu::Vec4>& data) const
{
	const tcu::Vec4		green		(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4		blue		(0.0f, 0.0f, 1.0f, 1.0f);
	std::vector<int>	cellOrder	(m_patternSide * m_patternSide * 2);
	de::Random			rnd			(0xDE12345);

	// generate crosshatch pattern with segments in random order
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
		cellOrder[ndx] = ndx;
	rnd.shuffle(cellOrder.begin(), cellOrder.end());

	data.resize(cellOrder.size() * 4);
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
	{
		const int segmentID		= cellOrder[ndx];
		const int direction		= segmentID & 0x01;
		const int majorCoord	= (segmentID >> 1) / m_patternSide;
		const int minorCoord	= (segmentID >> 1) % m_patternSide;

		if (direction)
		{
			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(minorCoord) / float(m_patternSide), float(majorCoord) / float(m_patternSide), 0.0f, 1.0f);
			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(minorCoord) / float(m_patternSide), float(majorCoord + 1) / float(m_patternSide), 0.0f, 1.0f);
			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
		}
		else
		{
			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(majorCoord) / float(m_patternSide), float(minorCoord) / float(m_patternSide), 0.0f, 1.0f);
			data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(majorCoord + 1) / float(m_patternSide), float(minorCoord) / float(m_patternSide), 0.0f, 1.0f);
			data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
		}
	}
}

void LineRenderCase::renderTestPattern (const IterationConfig& config)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	setupRender(config);

	if (m_hasTessellationStage)
	{
		const glw::GLint	tessLevelPos	= gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
		const glw::GLfloat	tessLevel		= 2.8f; // will be rounded up

		TCU_CHECK(tessLevelPos != -1);

		m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel << tcu::TestLog::EndMessage;

		gl.uniform1f(tessLevelPos, tessLevel);
		gl.patchParameteri(GL_PATCH_VERTICES, 2);
		GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
	}

	if (m_isWideLineCase)
		gl.lineWidth((float)m_wideLineLineWidth);

	gl.uniform1f(gl.getUniformLocation(m_program->getProgram(), "u_lineWidth"), (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f));

	m_testCtx.getLog() << tcu::TestLog::Message << "Rendering pattern." << tcu::TestLog::EndMessage;

	gl.enable(GL_BLEND);
	gl.blendFunc(GL_ONE, GL_ONE);
	gl.blendEquation(GL_FUNC_ADD);

	gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_LINES), 0, m_patternSide * m_patternSide * 2 * 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
}

void LineRenderCase::verifyRenderResult (const IterationConfig& config)
{
	const glw::Functions&	gl							= m_context.getRenderContext().getFunctions();
	const bool				isMsaa						= m_context.getRenderTarget().getNumSamples() > 1;
	const ProjectedBBox		projectedBBox				= projectBoundingBox(config.bbox);
	const float				lineWidth					= (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);
	const tcu::IVec4		viewportBBoxArea			= getViewportBoundingBoxArea(projectedBBox, config.viewportSize, lineWidth);
	const tcu::IVec4		viewportPatternArea			= getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
	const tcu::IVec2		expectedHorizontalLines		= getNumberOfLinesRange(viewportBBoxArea.y(), viewportBBoxArea.w(), config.patternPos.y(), config.patternSize.y(), config.viewportSize.y(), DIRECTION_VERTICAL);
	const tcu::IVec2		expectedVerticalLines		= getNumberOfLinesRange(viewportBBoxArea.x(), viewportBBoxArea.z(), config.patternPos.x(), config.patternSize.x(), config.viewportSize.x(), DIRECTION_HORIZONTAL);
	const tcu::IVec4		verificationArea			= tcu::IVec4(de::max(viewportBBoxArea.x(), 0),
																	 de::max(viewportBBoxArea.y(), 0),
																	 de::min(viewportBBoxArea.z(), config.viewportSize.x()),
																	 de::min(viewportBBoxArea.w(), config.viewportSize.y()));

	tcu::Surface			viewportSurface				(config.viewportSize.x(), config.viewportSize.y());
	int						messageLimitCounter			= 8;

	enum ScanResultCodes
	{
		SCANRESULT_NUM_LINES_ERR	= 0,
		SCANRESULT_LINE_WIDTH_MSAA	= 1,
		SCANRESULT_LINE_WIDTH_WARN	= 2,
		SCANRESULT_LINE_WIDTH_ERR	= 3,
		SCANRESULT_LINE_CONT_ERR	= 4,
		SCANRESULT_LINE_CONT_WARN	= 5,
		SCANRESULT_LINE_LAST
	};

	int						rowScanResult[SCANRESULT_LINE_LAST]		= {0, 0, 0, 0, 0, 0};
	int						columnScanResult[SCANRESULT_LINE_LAST]	= {0, 0, 0, 0, 0, 0};
	bool					anyError								= false;
	bool					msaaRelaxationRequired					= false;
	bool					hwIssueRelaxationRequired				= false;

	if (!m_calcPerPrimitiveBBox)
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Projected bounding box: (clip space)\n"
				<< "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
				<< "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
				<< "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
			<< "In viewport coordinates:\n"
				<< "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
				<< "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
			<< "Verifying render results within the bounding box:\n"
			<< tcu::TestLog::EndMessage;
	else
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying render result:"
			<< tcu::TestLog::EndMessage;

	m_testCtx.getLog()
		<< tcu::TestLog::Message
			<< "\tCalculating number of horizontal and vertical lines within the bounding box, expecting:\n"
			<< "\t[" << expectedHorizontalLines.x() << ", " << expectedHorizontalLines.y() << "] horizontal lines.\n"
			<< "\t[" << expectedVerticalLines.x() << ", " << expectedVerticalLines.y() << "] vertical lines.\n"
		<< tcu::TestLog::EndMessage;

	if (m_fbo)
		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
	glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(), viewportSurface.getAccess());

	// scan rows
	for (int y = de::max(verificationArea.y(), viewportPatternArea.y()); y < de::min(verificationArea.w(), viewportPatternArea.w()); ++y)
	{
		const deUint8 result = scanRow(viewportSurface.getAccess(),
									   y,
									   verificationArea.x(),
									   verificationArea.z(),
									   de::max(verificationArea.x(), viewportPatternArea.x()),
									   de::min(verificationArea.z(), viewportPatternArea.z()),
									   expectedVerticalLines,
									   messageLimitCounter);

		if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
			rowScanResult[SCANRESULT_NUM_LINES_ERR]++;
		if ((result & SCANRESULT_LINE_CONT_OK_BIT) == 0)
		{
			if ((result & SCANRESULT_LINE_CONT_WARN_BIT) != 0)
				rowScanResult[SCANRESULT_LINE_CONT_WARN]++;
			else
				rowScanResult[SCANRESULT_LINE_CONT_ERR]++;
		}
		else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
		{
			if (m_isWideLineCase && isMsaa)
			{
				// multisampled wide lines might not be supported
				rowScanResult[SCANRESULT_LINE_WIDTH_MSAA]++;
			}
			else if ((result & SCANRESULT_LINE_WIDTH_ERR_BIT) == 0 &&
					 (result & SCANRESULT_LINE_WIDTH_WARN_BIT) != 0)
			{
				rowScanResult[SCANRESULT_LINE_WIDTH_WARN]++;
			}
			else
				rowScanResult[SCANRESULT_LINE_WIDTH_ERR]++;
		}
	}

	// scan columns
	for (int x = de::max(verificationArea.x(), viewportPatternArea.x()); x < de::min(verificationArea.z(), viewportPatternArea.z()); ++x)
	{
		const deUint8 result = scanColumn(viewportSurface.getAccess(),
										  x,
										  verificationArea.y(),
										  verificationArea.w(),
										  de::min(verificationArea.y(), viewportPatternArea.y()),
										  de::min(verificationArea.w(), viewportPatternArea.w()),
										  expectedHorizontalLines,
										  messageLimitCounter);

		if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
			columnScanResult[SCANRESULT_NUM_LINES_ERR]++;
		if ((result & SCANRESULT_LINE_CONT_OK_BIT) == 0)
		{
			if ((result & SCANRESULT_LINE_CONT_WARN_BIT) != 0)
				columnScanResult[SCANRESULT_LINE_CONT_WARN]++;
			else
				columnScanResult[SCANRESULT_LINE_CONT_ERR]++;
		}
		else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
		{
			if (m_isWideLineCase && isMsaa)
			{
				// multisampled wide lines might not be supported
				columnScanResult[SCANRESULT_LINE_WIDTH_MSAA]++;
			}
			else if ((result & SCANRESULT_LINE_WIDTH_ERR_BIT) == 0 &&
					 (result & SCANRESULT_LINE_WIDTH_WARN_BIT) != 0)
			{
				columnScanResult[SCANRESULT_LINE_WIDTH_WARN]++;
			}
			else
				columnScanResult[SCANRESULT_LINE_WIDTH_ERR]++;
		}
	}

	if (columnScanResult[SCANRESULT_LINE_WIDTH_ERR] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_ERR] != 0)
		anyError = true;
	else if(columnScanResult[SCANRESULT_LINE_CONT_ERR] != 0 || rowScanResult[SCANRESULT_LINE_CONT_ERR] != 0)
		anyError = true;
	else if (columnScanResult[SCANRESULT_LINE_WIDTH_MSAA] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_MSAA] != 0)
		msaaRelaxationRequired = true;
	else if (columnScanResult[SCANRESULT_LINE_WIDTH_WARN] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_WARN] != 0)
		hwIssueRelaxationRequired = true;
	else if (columnScanResult[SCANRESULT_NUM_LINES_ERR] != 0)
	{
		// found missing lines in a columnw and row line continuity check reported a warning (not an error) -> line width precision issue
		if (rowScanResult[SCANRESULT_LINE_CONT_ERR] == 0 && rowScanResult[SCANRESULT_LINE_CONT_WARN])
			hwIssueRelaxationRequired = true;
		else
			anyError = true;
	}
	else if (rowScanResult[SCANRESULT_NUM_LINES_ERR] != 0)
	{
		// found missing lines in a row and column line continuity check reported a warning (not an error) -> line width precision issue
		if (columnScanResult[SCANRESULT_LINE_CONT_ERR] == 0 && columnScanResult[SCANRESULT_LINE_CONT_WARN])
			hwIssueRelaxationRequired = true;
		else
			anyError = true;
	}

	if (anyError || msaaRelaxationRequired || hwIssueRelaxationRequired)
	{
		if (messageLimitCounter < 0)
			m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (-messageLimitCounter) << " row/column error descriptions." << tcu::TestLog::EndMessage;

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
			<< tcu::TestLog::EndImageSet;

		if (anyError)
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
		else if (hwIssueRelaxationRequired)
		{
			// Line width hw issue
			m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Line width verification failed");
		}
		else
		{
			// MSAA wide lines are optional
			m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Multisampled wide line verification failed");
		}
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Result image ok."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
			<< tcu::TestLog::EndImageSet;
	}
}

tcu::IVec2 LineRenderCase::getNumberOfLinesRange (int queryAreaBegin, int queryAreaEnd, float patternStart, float patternSize, int viewportArea, QueryDirection queryDir) const
{
	// pattern is not symmetric due to mirroring
	const int	patternStartNdx	= (queryDir == DIRECTION_HORIZONTAL) ? ((m_hasGeometryStage) ? (1) : (0)) : ((m_hasTessellationStage) ? (1) : (0));
	const int	patternEndNdx	= patternStartNdx + m_patternSide;

	int			numLinesMin		= 0;
	int			numLinesMax		= 0;

	for (int lineNdx = patternStartNdx; lineNdx < patternEndNdx; ++lineNdx)
	{
		const float linePos		= (patternStart + (float(lineNdx) / float(m_patternSide)) * patternSize) * 0.5f + 0.5f;
		const float lineWidth	= (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);

		if (linePos * (float)viewportArea > (float)queryAreaBegin + 1.0f &&
			linePos * (float)viewportArea < (float)queryAreaEnd   - 1.0f)
		{
			// line center is within the area
			++numLinesMin;
			++numLinesMax;
		}
		else if (linePos * (float)viewportArea > (float)queryAreaBegin - lineWidth*0.5f - 1.0f &&
		         linePos * (float)viewportArea < (float)queryAreaEnd   + lineWidth*0.5f + 1.0f)
		{
			// line could leak into area
			++numLinesMax;
		}
	}

	return tcu::IVec2(numLinesMin, numLinesMax);
}

deUint8 LineRenderCase::scanRow (const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, int rowViewportBegin, int rowViewportEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
{
	const bool		numLinesOk			= checkAreaNumLines(access, tcu::IVec4(rowBegin, row, rowEnd - rowBegin, 1), messageLimitCounter, SCAN_ROW_COMPONENT_NDX, numLines);
	const deUint8	lineWidthRes		= checkLineWidths(access, tcu::IVec2(rowBegin, row), tcu::IVec2(rowEnd, row), SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
	const deUint8	lineContinuityRes	= checkLineContinuity(access, tcu::IVec2(rowViewportBegin, row), tcu::IVec2(rowViewportEnd, row), SCAN_COL_COMPONENT_NDX, messageLimitCounter);
	deUint8			result				= 0;

	if (numLinesOk)
		result |= (deUint8)SCANRESULT_NUM_LINES_OK_BIT;

	if (lineContinuityRes == 0)
		result |= (deUint8)SCANRESULT_LINE_CONT_OK_BIT;
	else
		result |= lineContinuityRes;

	if (lineWidthRes == 0)
		result |= (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT;
	else
		result |= lineWidthRes;

	return result;
}

deUint8 LineRenderCase::scanColumn (const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, int columnViewportBegin, int columnViewportEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
{
	const bool		numLinesOk			= checkAreaNumLines(access, tcu::IVec4(column, columnBegin, 1, columnEnd - columnBegin), messageLimitCounter, SCAN_COL_COMPONENT_NDX, numLines);
	const deUint8	lineWidthRes		= checkLineWidths(access, tcu::IVec2(column, columnBegin), tcu::IVec2(column, columnEnd), SCAN_COL_COMPONENT_NDX, messageLimitCounter);
	const deUint8	lineContinuityRes	= checkLineContinuity(access, tcu::IVec2(column, columnViewportBegin), tcu::IVec2(column, columnViewportEnd), SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
	deUint8			result				= 0;

	if (numLinesOk)
		result |= (deUint8)SCANRESULT_NUM_LINES_OK_BIT;

	if (lineContinuityRes == 0)
		result |= (deUint8)SCANRESULT_LINE_CONT_OK_BIT;
	else
		result |= lineContinuityRes;

	if (lineWidthRes == 0)
		result |= (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT;
	else
		result |= lineWidthRes;

	return result;
}

bool LineRenderCase::checkAreaNumLines (const tcu::ConstPixelBufferAccess& access, const tcu::IVec4& area, int& messageLimitCounter, int componentNdx, const tcu::IVec2& numLines) const
{
	// Num maxima == num lines
	const tcu::ConstPixelBufferAccess	subAccess		= tcu::getSubregion(access, area.x(), area.y(), 0, area.z(), area.w(), 1);
	const tcu::IVec2					numMinimaMaxima	= getNumMinimaMaxima(subAccess, componentNdx);
	const int							numMaxima		= numMinimaMaxima.y();

	// In valid range
	if (numMaxima >= numLines.x() && numMaxima <= numLines.y())
		return true;

	if (--messageLimitCounter < 0)
		return false;

	if (area.z() == 1)
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "On column " << area.x() << ", y: [" << area.y() << "," << (area.y()+area.w()) << "):\n"
				<< "\tExpected [" << numLines.x() << ", " << numLines.y() << "] lines but the number of lines in the area is " << numMaxima
			<< tcu::TestLog::EndMessage;
	else
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "On row " << area.y() << ", x: [" << area.x() << "," << (area.x()+area.z()) << "):\n"
				<< "\tExpected [" << numLines.x() << ", " << numLines.y() << "] lines but the number of lines in the area is " << numMaxima
			<< tcu::TestLog::EndMessage;

	return false;
}

tcu::IVec2 LineRenderCase::getNumMinimaMaxima (const tcu::ConstPixelBufferAccess& access, int componentNdx) const
{
	DE_ASSERT(access.getWidth() == 1 || access.getHeight() == 1);

	int previousValue	= -1;
	int previousSign	= 0;
	int numMinima		= 0;
	int numMaxima		= 0;

	for (int y = 0; y < access.getHeight(); ++y)
	for (int x = 0; x < access.getWidth(); ++x)
	{
		const int componentValue = access.getPixelInt(x, y)[componentNdx];

		if (previousValue != -1)
		{
			const int sign = (componentValue > previousValue) ? (+1) : (componentValue < previousValue) ? (-1) : (0);

			// local minima/maxima in sign changes (zero signless)
			if (sign != 0 && sign == -previousSign)
			{
				previousSign = sign;

				if (sign > 0)
					++numMinima;
				else
					++numMaxima;
			}
			else if (sign != 0 && previousSign == 0)
			{
				previousSign = sign;

				// local extreme at the start boundary
				if (sign > 0)
					++numMinima;
				else
					++numMaxima;
			}
		}

		previousValue = componentValue;
	}

	// local extreme at the end boundary
	if (previousSign > 0)
		++numMaxima;
	else if (previousSign < 0)
		++numMinima;
	else
	{
		++numMaxima;
		++numMinima;
	}

	return tcu::IVec2(numMinima, numMaxima);
}

deUint8 LineRenderCase::checkLineContinuity (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const
{
	bool				line					= false;
	const tcu::IVec2	advance					= (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
	int					missedPixels			= 0;
	int					totalPixels				= 0;
	deUint8				errorMask				= 0;

	for (tcu::IVec2 cursor = begin; cursor != end; cursor += advance)
	{
		const bool hit = (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0);

		if (hit)
			line = true;
		else if (line && !hit)
		{
			// non-continuous line detected
			const tcu::IVec2 advanceNeighbor	= tcu::IVec2(1, 1) - advance;
			const tcu::IVec2 cursorNeighborPos	= cursor + advanceNeighbor;
			const tcu::IVec2 cursorNeighborNeg	= cursor - advanceNeighbor;
			// hw precision issues may lead to a line being non-straight -> check neighboring pixels
			if ((access.getPixelInt(cursorNeighborPos.x(), cursorNeighborPos.y())[componentNdx] == 0) && (access.getPixelInt(cursorNeighborNeg.x(), cursorNeighborNeg.y())[componentNdx] == 0))
				++missedPixels;
		}
		++totalPixels;
	}

	if (missedPixels > 0)
	{
		if (--messageLimitCounter >= 0)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "Found non-continuous " << ((advance.x() == 1)  ? ("horizontal") : ("vertical")) << " line near " << begin << ". "
				<< "Missed pixels: " << missedPixels
				<< tcu::TestLog::EndMessage;
		}
		// allow 10% missing pixels for warning
		if (missedPixels <= deRoundFloatToInt32((float)totalPixels * 0.1f))
			errorMask = SCANRESULT_LINE_CONT_WARN_BIT;
		else
			errorMask =  SCANRESULT_LINE_CONT_ERR_BIT;
	}

	return errorMask;
}

deUint8 LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const
{
	const bool			multisample				= m_context.getRenderTarget().getNumSamples() > 1;
	const int			lineRenderWidth			= (m_isWideLineCase) ? (m_wideLineLineWidth) : 1;
	const tcu::IVec2	lineWidthRange			= (multisample)
													? (tcu::IVec2(lineRenderWidth, lineRenderWidth+1))	// multisampled "smooth" lines may spread to neighboring pixel
													: (tcu::IVec2(lineRenderWidth, lineRenderWidth));
	const tcu::IVec2	relaxedLineWidthRange	= (tcu::IVec2(lineRenderWidth-1, lineRenderWidth+1));

	int					lineWidth				= 0;
	bool				bboxLimitedLine			= false;
	deUint8				errorMask				= 0;

	const tcu::IVec2	advance					= (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));

	// fragments before begin?
	if (access.getPixelInt(begin.x(), begin.y())[componentNdx] != 0)
	{
		bboxLimitedLine = true;

		for (tcu::IVec2 cursor = begin - advance;; cursor -= advance)
		{
			if (cursor.x() < 0 || cursor.y() < 0)
			{
				break;
			}
			else if (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0)
			{
				++lineWidth;
			}
			else
				break;
		}
	}

	for (tcu::IVec2 cursor = begin; cursor != end; cursor += advance)
	{
		const bool hit = (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0);

		if (hit)
			++lineWidth;
		else if (lineWidth)
		{
			// Line is allowed to be be thinner if it borders the bbox boundary (since part of the line might have been discarded).
			const bool incorrectLineWidth = (lineWidth < lineWidthRange.x() && !bboxLimitedLine) || (lineWidth > lineWidthRange.y());

			if (incorrectLineWidth)
			{
				const bool incorrectRelaxedLineWidth = (lineWidth < relaxedLineWidthRange.x() && !bboxLimitedLine) || (lineWidth > relaxedLineWidthRange.y());

				if (incorrectRelaxedLineWidth)
					errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
				else
					errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;

				printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
			}

			lineWidth = 0;
			bboxLimitedLine = false;
		}
	}

	// fragments after end?
	if (lineWidth)
	{
		for (tcu::IVec2 cursor = end;; cursor += advance)
		{
			if (cursor.x() >= access.getWidth() || cursor.y() >= access.getHeight())
			{
				if (lineWidth > lineWidthRange.y())
				{
					if (lineWidth > relaxedLineWidthRange.y())
						errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
					else
						errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;

					printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
				}

				break;
			}
			else if (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0)
			{
				++lineWidth;
			}
			else if (lineWidth)
			{
				// only check that line width is not larger than expected. Line width may be smaller
				// since the scanning 'cursor' is now outside the bounding box.
				const bool incorrectLineWidth = (lineWidth > lineWidthRange.y());

				if (incorrectLineWidth)
				{
					const bool incorrectRelaxedLineWidth = (lineWidth > relaxedLineWidthRange.y());

					if (incorrectRelaxedLineWidth)
						errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
					else
						errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;

					printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
				}

				lineWidth = 0;
			}
		}
	}

	return errorMask;
}

void LineRenderCase::printLineWidthError (const tcu::IVec2& pos, int detectedLineWidth, const tcu::IVec2& lineWidthRange, bool isHorizontal, int& messageLimitCounter) const
{
	if (--messageLimitCounter < 0)
		return;

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Found incorrect line width near " << pos << ": (" << ((isHorizontal) ? ("horizontal") : ("vertical")) << " line)\n"
			<< "\tExpected line width in range [" << lineWidthRange.x() << ", " << lineWidthRange.y() << "] but found " << detectedLineWidth
		<< tcu::TestLog::EndMessage;
}

class PointRenderCase : public BBoxRenderCase
{
public:
	enum
	{
		POINTFLAG_WIDE = 1u << FLAGBIT_USER_BIT,	//!< use wide points
	};
	struct GeneratedPoint
	{
		tcu::Vec2	center;
		int			size;
		bool		even;
	};

							PointRenderCase					(Context& context, const char* name, const char* description, deUint32 flags);
							~PointRenderCase				(void);

private:
	enum ResultPointType
	{
		POINT_FULL = 0,
		POINT_PARTIAL
	};

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

	std::string				genVertexSource					(void) const;
	std::string				genFragmentSource				(void) const;
	std::string				genTessellationControlSource	(void) const;
	std::string				genTessellationEvaluationSource	(void) const;
	std::string				genGeometrySource				(void) const;

	IterationConfig			generateConfig					(int iteration, const tcu::IVec2& renderTargetSize) const;
	void					generateAttributeData			(void);
	void					getAttributeData				(std::vector<tcu::Vec4>& data) const;
	void					renderTestPattern				(const IterationConfig& config);
	void					verifyRenderResult				(const IterationConfig& config);

	void					genReferencePointData			(const IterationConfig& config, std::vector<GeneratedPoint>& data) const;
	bool					verifyNarrowPointPattern		(const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter);
	bool					verifyWidePointPattern			(const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter);
	bool					verifyWidePoint					(const tcu::Surface& viewport, const GeneratedPoint& refPoint, const ProjectedBBox& bbox, ResultPointType pointType, int& logFloodCounter);
	bool					verifyWidePointAt				(const tcu::IVec2& pointPos, const tcu::Surface& viewport, const GeneratedPoint& refPoint, const tcu::IVec4& bbox, ResultPointType pointType, int componentNdx, int& logFloodCounter);
	tcu::IVec2				scanPointWidthAt				(const tcu::IVec2& pointPos, const tcu::Surface& viewport, int expectedPointSize, int componentNdx) const;

	const int				m_numStripes;
	const bool				m_isWidePointCase;
	std::vector<tcu::Vec4>	m_attribData;
};

PointRenderCase::PointRenderCase (Context& context, const char* name, const char* description, deUint32 flags)
	: BBoxRenderCase	(context, name, description, 12, flags)
	, m_numStripes		(4)
	, m_isWidePointCase	((flags & POINTFLAG_WIDE) != 0)
{
}

PointRenderCase::~PointRenderCase (void)
{
}

void PointRenderCase::init (void)
{
	if (m_isWidePointCase)
	{
		const bool supportsGL45 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));

		if (!supportsGL45) {
			// extensions
			if (m_hasGeometryStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_point_size"))
				throw tcu::NotSupportedError("Test requires GL_EXT_geometry_point_size extension");
			if (m_hasTessellationStage && !m_hasGeometryStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_point_size"))
				throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_point_size extension");
		}

		// Enable program point size for desktop GL
		if (supportsGL45) {
			const glw::Functions& gl = m_context.getRenderContext().getFunctions();
			gl.enable(GL_PROGRAM_POINT_SIZE);
		}

		// point size range
		{
			glw::GLfloat pointSizeRange[2] = {0.0f, 0.0f};
			m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);

			if (pointSizeRange[1] < 5.0f)
				throw tcu::NotSupportedError("Test requires point size 5.0");
		}
	}

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Rendering point pattern to " << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
		<< "Half of the points are green, half blue. Using additive blending.\n"
		<< "Points are in random order, varying pattern size and location for each iteration.\n"
		<< "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated red channel."
		<< tcu::TestLog::EndMessage;

	generateAttributeData();

	BBoxRenderCase::init();
}

void PointRenderCase::deinit (void)
{
	// clear data
	m_attribData = std::vector<tcu::Vec4>();

	// deinit parent
	BBoxRenderCase::deinit();
}

std::string PointRenderCase::genVertexSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in highp vec4 a_position;\n"
			"in highp vec4 a_color;\n"
			"out highp vec4 vtx_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"\n";
	if (!m_hasTessellationStage)
	{
		DE_ASSERT(m_useGlobalState);
		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
				"uniform highp vec4 u_primitiveBBoxMax;\n"
				"\n"
				"flat out highp float v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize;\n"
				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
				"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
				"\n";
	}

	buf <<	"void main()\n"
			"{\n"
			"	highp vec2 patternOffset = u_posScale.xy;\n"
			"	highp vec2 patternScale = u_posScale.zw;\n"
			"	highp float pointSize = "
					<< ((m_isWidePointCase && !m_hasTessellationStage && !m_hasGeometryStage) ? ("(a_color.g > 0.0) ? (5.0) : (3.0)") : ("1.0"))
					<< ";\n"
		<<	"	gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
			"	gl_PointSize = pointSize;\n"
			"	vtx_color = a_color;\n";

	if (!m_hasTessellationStage)
	{
		DE_ASSERT(m_useGlobalState);
		buf <<	"\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_expansionSize = pointSize;\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin =\n"
				"	    min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMin.w,\n"
				"	        vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / u_primitiveBBoxMax.w);\n"
				"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax =\n"
				"	    min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMin.w,\n"
				"	        vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / u_primitiveBBoxMax.w);\n";
	}

	buf <<	"}\n";
	return buf.str();
}

std::string PointRenderCase::genFragmentSource (void) const
{
	const char* const	colorInputName = (m_hasGeometryStage) ? ("geo_color") : (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in mediump vec4 " << colorInputName << ";\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
		<<	genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
		<<	"\n"
			"void main()\n"
			"{\n"
			"	mediump vec4 baseColor = " << colorInputName << ";\n"
			"	mediump float redChannel;\n"
			"	if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
			"		redChannel = 0.0;\n"
			"	else\n"
			"		redChannel = 1.0;\n"
			"	o_color = vec4(redChannel, baseColor.g, baseColor.b, baseColor.a);\n"
			"}\n";

	return buf.str();
}

std::string PointRenderCase::genTessellationControlSource (void) const
{
	const bool			tessellationWidePoints = (m_isWidePointCase) && (!m_hasGeometryStage);
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
		<<	((tessellationWidePoints) ? ("${TESSELLATION_POINT_SIZE_REQUIRE}\n") : (""))
		<<	"layout(vertices=1) out;"
			"\n"
			"in highp vec4 vtx_color[];\n"
			"out highp vec4 tess_ctrl_color[];\n"
			"uniform highp float u_tessellationLevel;\n"
			"uniform highp vec4 u_posScale;\n";

	if (!m_calcPerPrimitiveBBox)
	{
		buf <<	"uniform highp vec4 u_primitiveBBoxMin;\n"
				"uniform highp vec4 u_primitiveBBoxMax;\n";
	}

	buf <<	"patch out highp vec3 vp_bbox_clipMin;\n"
			"patch out highp vec3 vp_bbox_clipMax;\n";

	if (m_calcPerPrimitiveBBox)
	{
		buf <<	"\n";
		if (m_hasGeometryStage)
			buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
		buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);

		buf <<	"vec4 transformVec(in highp vec4 p)\n"
				"{\n"
				"	return " << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)")) << ";\n"
				"}\n";
	}

	buf <<	"\n"
			"void main()\n"
			"{\n"
			"	// convert to nonsensical coordinates, just in case\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
			"	tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
			"\n"
			"	gl_TessLevelOuter[0] = u_tessellationLevel;\n"
			"	gl_TessLevelOuter[1] = u_tessellationLevel;\n"
			"	gl_TessLevelOuter[2] = u_tessellationLevel;\n"
			"	gl_TessLevelOuter[3] = u_tessellationLevel;\n"
			"	gl_TessLevelInner[0] = 0.8; // will be rounded up to 1\n"
			"	gl_TessLevelInner[1] = 0.8; // will be rounded up to 1\n";

	if (m_calcPerPrimitiveBBox)
	{
		buf <<	"\n";

		if (m_hasGeometryStage)
			buf <<	"	const vec2 minExpansion = vec2(0.07 + 0.05, 0.07 + 0.02); // eval and geometry shader\n"
					"	const vec2 maxExpansion = vec2(0.07 + 0.05, 0.07 + 0.03); // eval and geometry shader\n";
		else
			buf <<	"	const vec2 minExpansion = vec2(0.07, 0.07); // eval shader\n"
					"	const vec2 maxExpansion = vec2(0.07, 0.07); // eval shader\n";

		buf <<	"	highp vec2 patternScale = u_posScale.zw;\n"
				"	highp vec4 bboxMin = transformVec(gl_in[0].gl_Position) - vec4(minExpansion * patternScale, 0.0, 0.0);\n"
				"	highp vec4 bboxMax = transformVec(gl_in[0].gl_Position) + vec4(maxExpansion * patternScale, 0.0, 0.0);\n";
	}
	else
	{
		buf <<	"\n"
				"	highp vec4 bboxMin = u_primitiveBBoxMin;\n"
				"	highp vec4 bboxMax = u_primitiveBBoxMax;\n";
	}
	if (!m_useGlobalState)
		buf <<	"\n"
				"	${PRIM_GL_BOUNDING_BOX}[0] = bboxMin;\n"
				"	${PRIM_GL_BOUNDING_BOX}[1] = bboxMax;\n";

	buf <<	"	vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
			"	                      vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
			"	vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
			"	                      vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
			"}\n";

	return buf.str();
}

std::string PointRenderCase::genTessellationEvaluationSource (void) const
{
	const bool			tessellationWidePoints = (m_isWidePointCase) && (!m_hasGeometryStage);
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
		<<	((tessellationWidePoints) ? ("${TESSELLATION_POINT_SIZE_REQUIRE}\n") : (""))
		<<	"layout(quads, point_mode) in;"
			"\n"
			"in highp vec4 tess_ctrl_color[];\n"
			"out highp vec4 tess_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"\n"
			"patch in highp vec3 vp_bbox_clipMin;\n"
			"patch in highp vec3 vp_bbox_clipMax;\n"
		<<	((!m_hasGeometryStage) ? ("flat out highp float v_bbox_expansionSize;\n") : (""))
		<<	"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin;\n"
			"flat out highp vec3 v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
			"\n"
		<<	genShaderFunction(SHADER_FUNC_MIRROR_Y)
		<<	"void main()\n"
			"{\n"
			"	// non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
			"	highp vec2 patternScale = u_posScale.zw;\n"
			"	highp vec4 offset = vec4((gl_TessCoord.xy * 2.0 - vec2(1.0)) * 0.07 * patternScale, 0.0, 0.0);\n"
			"	highp float pointSize = " << ((tessellationWidePoints) ? ("(tess_ctrl_color[0].g > 0.0) ? (5.0) : (3.0)") : ("1.0")) << ";\n"
			"	gl_Position = mirrorY(gl_in[0].gl_Position.zwyx + offset);\n";

	if (tessellationWidePoints)
		buf << "	gl_PointSize = pointSize;\n";

	buf <<	"	tess_color = tess_ctrl_color[0];\n"
		<<	((!m_hasGeometryStage) ? ("v_bbox_expansionSize = pointSize;\n") : (""))
		<<	"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMin = vp_bbox_clipMin;\n"
			"	v_" << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax = vp_bbox_clipMax;\n"
			"}\n";

	return buf.str();
}

std::string PointRenderCase::genGeometrySource (void) const
{
	const char* const	colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GEOMETRY_SHADER_REQUIRE}\n"
		<<	((m_isWidePointCase) ? ("${GEOMETRY_POINT_SIZE}\n") : (""))
		<<	"layout(points) in;\n"
			"layout(max_vertices=3, points) out;\n"
			"\n"
			"in highp vec4 " << colorInputName << "[1];\n"
			"out highp vec4 geo_color;\n"
			"uniform highp vec4 u_posScale;\n"
			"\n"
			"flat in highp vec3 v_geo_bbox_clipMin[1];\n"
			"flat in highp vec3 v_geo_bbox_clipMax[1];\n"
			"flat out highp vec3 v_bbox_clipMin;\n"
			"flat out highp vec3 v_bbox_clipMax;\n"
			"flat out highp float v_bbox_expansionSize;\n"
			"\n"
		<<	genShaderFunction(SHADER_FUNC_MIRROR_X)
		<<	"\n"
			"void main()\n"
			"{\n"
			"	// Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
			"	highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
			"	highp vec4 pointColor = " << colorInputName << "[0];\n"
			"	highp vec2 patternScale = u_posScale.zw;\n"
			"	highp float pointSize = "
				<< (m_isWidePointCase ? ("(pointColor.g > 0.0) ? (5.0) : (3.0)") : ("1.0"))
				<< ";\n"
			"\n"
			"	highp vec4 offsets[3] =\n"
			"		vec4[3](\n"
			"			vec4( 0.05 * patternScale.x, 0.03 * patternScale.y, 0.0, 0.0),\n"
			"			vec4(-0.01 * patternScale.x,-0.02 * patternScale.y, 0.0, 0.0),\n"
			"			vec4(-0.05 * patternScale.x, 0.02 * patternScale.y, 0.0, 0.0)\n"
			"		);\n"
			"	for (int ndx = 0; ndx < 3; ++ndx)\n"
			"	{\n"
			"		gl_Position = p0 + offsets[ndx];\n";

	if (m_isWidePointCase)
		buf <<	"		gl_PointSize = pointSize;\n";

	buf <<	"		v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
			"		v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
			"		v_bbox_expansionSize = pointSize;\n"
			"		geo_color = pointColor;\n"
			"		EmitVertex();\n"
			"	}\n"
			"}\n";

	return buf.str();
}

PointRenderCase::IterationConfig PointRenderCase::generateConfig (int iteration, const tcu::IVec2& renderTargetSize) const
{
	IterationConfig config = generateRandomConfig(0xDEDEDEu * (deUint32)iteration, renderTargetSize);

	// equal or larger -> expand according to shader expansion
	if (m_bboxSize == BBOXSIZE_EQUAL || m_bboxSize == BBOXSIZE_LARGER)
	{
		const tcu::Vec2 patternScale = config.patternSize;

		if (m_hasTessellationStage)
		{
			config.bbox.min -= tcu::Vec4(0.07f * patternScale.x(), 0.07f * patternScale.y(), 0.0f, 0.0f);
			config.bbox.max += tcu::Vec4(0.07f * patternScale.x(), 0.07f * patternScale.y(), 0.0f, 0.0f);
		}
		if (m_hasGeometryStage)
		{
			config.bbox.min -= tcu::Vec4(0.05f * patternScale.x(), 0.02f * patternScale.y(), 0.0f, 0.0f);
			config.bbox.max += tcu::Vec4(0.05f * patternScale.x(), 0.03f * patternScale.y(), 0.0f, 0.0f);
		}
	}

	return config;
}

void PointRenderCase::generateAttributeData (void)
{
	const tcu::Vec4		green		(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4		blue		(0.0f, 0.0f, 1.0f, 1.0f);
	std::vector<int>	cellOrder	(m_numStripes * m_numStripes * 2);
	de::Random			rnd			(0xDE22446);

	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
		cellOrder[ndx] = ndx;
	rnd.shuffle(cellOrder.begin(), cellOrder.end());

	m_attribData.resize(cellOrder.size() * 2);
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
	{
		const int pointID		= cellOrder[ndx];
		const int direction		= pointID & 0x01;
		const int majorCoord	= (pointID >> 1) / m_numStripes;
		const int minorCoord	= (pointID >> 1) % m_numStripes;

		if (direction)
		{
			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(float(minorCoord) / float(m_numStripes), float(majorCoord) / float(m_numStripes), 0.0f, 1.0f);
			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
		}
		else
		{
			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(((float)majorCoord + 0.5f) / float(m_numStripes), ((float)minorCoord + 0.5f) / float(m_numStripes), 0.0f, 1.0f);
			m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
		}
	}
}

void PointRenderCase::getAttributeData (std::vector<tcu::Vec4>& data) const
{
	data = m_attribData;
}

void PointRenderCase::renderTestPattern (const IterationConfig& config)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	setupRender(config);

	if (m_hasTessellationStage)
	{
		const glw::GLint	tessLevelPos	= gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
		const glw::GLfloat	tessLevel		= 0.8f; // will be rounded up

		TCU_CHECK(tessLevelPos != -1);

		m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel << tcu::TestLog::EndMessage;

		gl.uniform1f(tessLevelPos, tessLevel);
		gl.patchParameteri(GL_PATCH_VERTICES, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
	}

	m_testCtx.getLog() << tcu::TestLog::Message << "Rendering pattern." << tcu::TestLog::EndMessage;

	gl.enable(GL_BLEND);
	gl.blendFunc(GL_ONE, GL_ONE);
	gl.blendEquation(GL_FUNC_ADD);

	gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_POINTS), 0, m_numStripes * m_numStripes * 2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
}

void PointRenderCase::verifyRenderResult (const IterationConfig& config)
{
	const glw::Functions&		gl						= m_context.getRenderContext().getFunctions();
	const ProjectedBBox			projectedBBox			= projectBoundingBox(config.bbox);
	const tcu::IVec4			viewportBBoxArea		= getViewportBoundingBoxArea(projectedBBox, config.viewportSize);

	tcu::Surface				viewportSurface			(config.viewportSize.x(), config.viewportSize.y());
	int							logFloodCounter			= 8;
	bool						anyError;
	std::vector<GeneratedPoint>	refPoints;

	if (!m_calcPerPrimitiveBBox)
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Projected bounding box: (clip space)\n"
				<< "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
				<< "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
				<< "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
			<< "In viewport coordinates:\n"
				<< "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
				<< "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
			<< "Verifying render results within the bounding box:\n"
			<< tcu::TestLog::EndMessage;
	else
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying render result:"
			<< tcu::TestLog::EndMessage;

	if (m_fbo)
		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
	glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(), viewportSurface.getAccess());

	genReferencePointData(config, refPoints);

	if (m_isWidePointCase)
		anyError = verifyWidePointPattern(viewportSurface, refPoints, projectedBBox, logFloodCounter);
	else
		anyError = verifyNarrowPointPattern(viewportSurface, refPoints, projectedBBox, logFloodCounter);

	if (anyError)
	{
		if (logFloodCounter < 0)
			m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (-logFloodCounter) << " error descriptions." << tcu::TestLog::EndMessage;

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
			<< tcu::TestLog::EndImageSet;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Result image ok."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
			<< tcu::TestLog::EndImageSet;
	}
}

struct PointSorter
{
	bool operator() (const PointRenderCase::GeneratedPoint& a, const PointRenderCase::GeneratedPoint& b) const
	{
		if (a.center.y() < b.center.y())
			return true;
		else if (a.center.y() > b.center.y())
			return false;
		else
			return (a.center.x() < b.center.x());
	}
};

void PointRenderCase::genReferencePointData (const IterationConfig& config, std::vector<GeneratedPoint>& data) const
{
	std::vector<GeneratedPoint> currentPoints;

	// vertex shader
	currentPoints.resize(m_attribData.size() / 2);
	for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
	{
		currentPoints[ndx].center	= m_attribData[ndx*2].swizzle(0, 1);
		currentPoints[ndx].even		= (m_attribData[ndx*2 + 1].y() == 1.0f); // is green
		currentPoints[ndx].size		= ((m_isWidePointCase) ? ((currentPoints[ndx].even) ? 5 : 3) : 1);
	}

	// tessellation
	if (m_hasTessellationStage)
	{
		std::vector<GeneratedPoint> tessellatedPoints;

		tessellatedPoints.resize(currentPoints.size() * 4);
		for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
		{
			const tcu::Vec2 position = tcu::Vec2(currentPoints[ndx].center.x(), 1.0f - currentPoints[ndx].center.y()); // mirror Y

			tessellatedPoints[4 * ndx + 0].center	= position + tcu::Vec2(-0.07f, -0.07f);
			tessellatedPoints[4 * ndx + 0].size		= currentPoints[ndx].size;
			tessellatedPoints[4 * ndx + 0].even		= currentPoints[ndx].even;

			tessellatedPoints[4 * ndx + 1].center	= position + tcu::Vec2( 0.07f, -0.07f);
			tessellatedPoints[4 * ndx + 1].size		= currentPoints[ndx].size;
			tessellatedPoints[4 * ndx + 1].even		= currentPoints[ndx].even;

			tessellatedPoints[4 * ndx + 2].center	= position + tcu::Vec2( 0.07f,  0.07f);
			tessellatedPoints[4 * ndx + 2].size		= currentPoints[ndx].size;
			tessellatedPoints[4 * ndx + 2].even		= currentPoints[ndx].even;

			tessellatedPoints[4 * ndx + 3].center	= position + tcu::Vec2(-0.07f,  0.07f);
			tessellatedPoints[4 * ndx + 3].size		= currentPoints[ndx].size;
			tessellatedPoints[4 * ndx + 3].even		= currentPoints[ndx].even;
		}

		currentPoints.swap(tessellatedPoints);
	}

	// geometry
	if (m_hasGeometryStage)
	{
		std::vector<GeneratedPoint> geometryShadedPoints;

		geometryShadedPoints.resize(currentPoints.size() * 3);
		for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
		{
			const tcu::Vec2 position = tcu::Vec2(1.0f - currentPoints[ndx].center.x(), currentPoints[ndx].center.y()); // mirror X

			geometryShadedPoints[3 * ndx + 0].center	= position + tcu::Vec2( 0.05f,  0.03f);
			geometryShadedPoints[3 * ndx + 0].size		= currentPoints[ndx].size;
			geometryShadedPoints[3 * ndx + 0].even		= currentPoints[ndx].even;

			geometryShadedPoints[3 * ndx + 1].center	= position + tcu::Vec2(-0.01f, -0.02f);
			geometryShadedPoints[3 * ndx + 1].size		= currentPoints[ndx].size;
			geometryShadedPoints[3 * ndx + 1].even		= currentPoints[ndx].even;

			geometryShadedPoints[3 * ndx + 2].center	= position + tcu::Vec2(-0.05f,  0.02f);
			geometryShadedPoints[3 * ndx + 2].size		= currentPoints[ndx].size;
			geometryShadedPoints[3 * ndx + 2].even		= currentPoints[ndx].even;
		}

		currentPoints.swap(geometryShadedPoints);
	}

	// sort from left to right, top to bottom
	std::sort(currentPoints.begin(), currentPoints.end(), PointSorter());

	// map to pattern space
	for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
		currentPoints[ndx].center = currentPoints[ndx].center * config.patternSize + config.patternPos;

	currentPoints.swap(data);
}

bool PointRenderCase::verifyNarrowPointPattern (const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter)
{
	bool anyError = false;

	// check that there is something near each sample
	for (int pointNdx = 0; pointNdx < (int)refPoints.size(); ++pointNdx)
	{
		const float				epsilon		= 1.0e-6f;
		const GeneratedPoint&	refPoint	= refPoints[pointNdx];

		// skip points not in the the bbox, treat boundary as "in"
		if (refPoint.center.x() < bbox.min.x() - epsilon ||
			refPoint.center.y() < bbox.min.y() - epsilon ||
			refPoint.center.x() > bbox.max.x() + epsilon ||
			refPoint.center.y() > bbox.max.y() + epsilon)
			continue;
		else
		{
			// transform to viewport coords
			const tcu::IVec2 pixelCenter(deRoundFloatToInt32((refPoint.center.x() * 0.5f + 0.5f) * (float)viewport.getWidth()),
										 deRoundFloatToInt32((refPoint.center.y() * 0.5f + 0.5f) * (float)viewport.getHeight()));

			// find rasterized point in the result
			if (pixelCenter.x() < 1 || pixelCenter.y() < 1 || pixelCenter.x() >= viewport.getWidth()-1 || pixelCenter.y() >= viewport.getHeight()-1)
			{
				// viewport boundary, assume point is fine
			}
			else
			{
				const int	componentNdx	= (refPoint.even) ? (1) : (2); // analyze either green or blue channel
				bool		foundResult		= false;

				// check neighborhood
				for (int dy = -1; dy < 2 && !foundResult; ++dy)
				for (int dx = -1; dx < 2 && !foundResult; ++dx)
				{
					const tcu::IVec2	testPos	(pixelCenter.x() + dx, pixelCenter.y() + dy);
					const tcu::RGBA		color	= viewport.getPixel(testPos.x(), testPos.y());

					if (color.toIVec()[componentNdx] > 0)
						foundResult = true;
				}

				if (!foundResult)
				{
					anyError = true;

					if (--logFloodCounter >= 0)
					{
						m_testCtx.getLog()
							<< tcu::TestLog::Message
							<< "Missing point near " << pixelCenter << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
							<< tcu::TestLog::EndMessage;
					}
				}
			}
		}
	}

	return anyError;
}

bool PointRenderCase::verifyWidePointPattern (const tcu::Surface& viewport, const std::vector<GeneratedPoint>& refPoints, const ProjectedBBox& bbox, int& logFloodCounter)
{
	bool anyError = false;

	// check that there is something near each sample
	for (int pointNdx = 0; pointNdx < (int)refPoints.size(); ++pointNdx)
	{
		const GeneratedPoint& refPoint = refPoints[pointNdx];

		if (refPoint.center.x() >= bbox.min.x() &&
			refPoint.center.y() >= bbox.min.y() &&
			refPoint.center.x() <= bbox.max.x() &&
			refPoint.center.y() <= bbox.max.y())
		{
			// point fully in the bounding box
			anyError |= !verifyWidePoint(viewport, refPoint, bbox, POINT_FULL, logFloodCounter);
		}
		else if (refPoint.center.x() >= bbox.min.x() + (float)refPoint.size / 2.0f &&
				 refPoint.center.y() >= bbox.min.y() - (float)refPoint.size / 2.0f &&
				 refPoint.center.x() <= bbox.max.x() + (float)refPoint.size / 2.0f &&
				 refPoint.center.y() <= bbox.max.y() - (float)refPoint.size / 2.0f)
		{
			// point leaks into bounding box
			anyError |= !verifyWidePoint(viewport, refPoint, bbox, POINT_PARTIAL, logFloodCounter);
		}
	}

	return anyError;
}

bool PointRenderCase::verifyWidePoint (const tcu::Surface& viewport, const GeneratedPoint& refPoint, const ProjectedBBox& bbox, ResultPointType pointType, int& logFloodCounter)
{
	const int			componentNdx		= (refPoint.even) ? (1) : (2);
	const int			halfPointSizeCeil	= (refPoint.size + 1) / 2;
	const int			halfPointSizeFloor	= (refPoint.size + 1) / 2;
	const tcu::IVec4	viewportBBoxArea	= getViewportBoundingBoxArea(bbox, tcu::IVec2(viewport.getWidth(), viewport.getHeight()), (float)refPoint.size);
	const tcu::IVec4	verificationArea	= tcu::IVec4(de::max(viewportBBoxArea.x(), 0),
														 de::max(viewportBBoxArea.y(), 0),
														 de::min(viewportBBoxArea.z(), viewport.getWidth()),
														 de::min(viewportBBoxArea.w(), viewport.getHeight()));
	const tcu::IVec2	pointPos			= tcu::IVec2(deRoundFloatToInt32((refPoint.center.x()*0.5f + 0.5f) * (float)viewport.getWidth()),
														 deRoundFloatToInt32((refPoint.center.y()*0.5f + 0.5f) * (float)viewport.getHeight()));

	// find any fragment within the point that is inside the bbox, start search at the center

	if (pointPos.x() >= verificationArea.x() &&
		pointPos.y() >= verificationArea.y() &&
		pointPos.x() < verificationArea.z() &&
		pointPos.y() < verificationArea.w())
	{
		if (viewport.getPixel(pointPos.x(), pointPos.y()).toIVec()[componentNdx])
			return verifyWidePointAt(pointPos, viewport, refPoint, verificationArea, pointType, componentNdx, logFloodCounter);
	}

	for (int dy = -halfPointSizeCeil; dy <= halfPointSizeCeil; ++dy)
	for (int dx = -halfPointSizeCeil; dx <= halfPointSizeCeil; ++dx)
	{
		const tcu::IVec2 testPos = pointPos + tcu::IVec2(dx, dy);

		if (dx == 0 && dy == 0)
			continue;

		if (testPos.x() >= verificationArea.x() &&
			testPos.y() >= verificationArea.y() &&
			testPos.x() < verificationArea.z() &&
			testPos.y() < verificationArea.w())
		{
			if (viewport.getPixel(testPos.x(), testPos.y()).toIVec()[componentNdx])
				return verifyWidePointAt(testPos, viewport, refPoint, verificationArea, pointType, componentNdx, logFloodCounter);
		}
	}

	// could not find point, this is only ok near boundaries
	if (pointPos.x() + halfPointSizeFloor <  verificationArea.x() - 1 ||
		pointPos.y() + halfPointSizeFloor <  verificationArea.y() - 1 ||
		pointPos.x() - halfPointSizeFloor >= verificationArea.z() - 1 ||
		pointPos.y() - halfPointSizeFloor >= verificationArea.w() - 1)
		return true;

	if (--logFloodCounter >= 0)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Missing wide point near " << pointPos << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
			<< tcu::TestLog::EndMessage;
	}

	return false;
}

bool PointRenderCase::verifyWidePointAt (const tcu::IVec2& pointPos, const tcu::Surface& viewport, const GeneratedPoint& refPoint, const tcu::IVec4& bbox, ResultPointType pointType, int componentNdx, int& logFloodCounter)
{
	const int				expectedPointSize		= refPoint.size;
	bool					viewportClippedTop		= false;
	bool					viewportClippedBottom	= false;
	bool					primitiveClippedTop		= false;
	bool					primitiveClippedBottom	= false;
	std::vector<tcu::IVec2>	widthsUpwards;
	std::vector<tcu::IVec2>	widthsDownwards;
	std::vector<tcu::IVec2>	widths;

	// search upwards
	for (int y = pointPos.y();; --y)
	{
		if (y < bbox.y() || y < 0)
		{
			if (y < bbox.y())
				primitiveClippedTop = true;
			if (y < 0)
				viewportClippedTop = true;
			break;
		}
		else if (pointPos.y() - y > expectedPointSize)
		{
			// no need to go further than point height
			break;
		}
		else if (viewport.getPixel(pointPos.x(), y).toIVec()[componentNdx] == 0)
		{
			break;
		}
		else
		{
			widthsUpwards.push_back(scanPointWidthAt(tcu::IVec2(pointPos.x(), y), viewport, expectedPointSize, componentNdx));
		}
	}

	// top is clipped
	if ((viewportClippedTop || (pointType == POINT_PARTIAL && primitiveClippedTop)) && !widthsUpwards.empty())
	{
		const tcu::IVec2&	range			= widthsUpwards.back();
		const bool			squareFits		= (range.y() - range.x() + 1) >= expectedPointSize;
		const bool			widthClipped	= (pointType == POINT_PARTIAL) && (range.x() <= bbox.x() || range.y() >= bbox.z());

		if (squareFits || widthClipped)
			return true;
	}

	// and downwards
	for (int y = pointPos.y()+1;; ++y)
	{
		if (y >= bbox.w() || y >= viewport.getHeight())
		{
			if (y >= bbox.w())
				primitiveClippedBottom = true;
			if (y >= viewport.getHeight())
				viewportClippedBottom = true;
			break;
		}
		else if (y - pointPos.y() > expectedPointSize)
		{
			// no need to go further than point height
			break;
		}
		else if (viewport.getPixel(pointPos.x(), y).toIVec()[componentNdx] == 0)
		{
			break;
		}
		else
		{
			widthsDownwards.push_back(scanPointWidthAt(tcu::IVec2(pointPos.x(), y), viewport, expectedPointSize, componentNdx));
		}
	}

	// bottom is clipped
	if ((viewportClippedBottom || (pointType == POINT_PARTIAL && primitiveClippedBottom)) && !(widthsDownwards.empty() && widthsUpwards.empty()))
	{
		const tcu::IVec2&	range			= (widthsDownwards.empty()) ? (widthsUpwards.front()) : (widthsDownwards.back());
		const bool			squareFits		= (range.y() - range.x() + 1) >= expectedPointSize;
		const bool			bboxClipped		= (pointType == POINT_PARTIAL) && (range.x() <= bbox.x() || range.y() >= bbox.z()-1);
		const bool			viewportClipped	= range.x() <= 0 || range.y() >= viewport.getWidth()-1;

		if (squareFits || bboxClipped || viewportClipped)
			return true;
	}

	// would square point would fit into the rasterized area

	for (int ndx = 0; ndx < (int)widthsUpwards.size(); ++ndx)
		widths.push_back(widthsUpwards[(int)widthsUpwards.size() - ndx - 1]);
	for (int ndx = 0; ndx < (int)widthsDownwards.size(); ++ndx)
		widths.push_back(widthsDownwards[ndx]);
	DE_ASSERT(!widths.empty());

	for (int y = 0; y < (int)widths.size() - expectedPointSize + 1; ++y)
	{
		tcu::IVec2 unionRange = widths[y];

		for (int dy = 1; dy < expectedPointSize; ++dy)
		{
			unionRange.x() = de::max(unionRange.x(), widths[y+dy].x());
			unionRange.y() = de::min(unionRange.y(), widths[y+dy].y());
		}

		// would a N x N block fit here?
		{
			const bool squareFits		= (unionRange.y() - unionRange.x() + 1) >= expectedPointSize;
			const bool bboxClipped		= (pointType == POINT_PARTIAL) && (unionRange.x() <= bbox.x() || unionRange.y() >= bbox.z()-1);
			const bool viewportClipped	= unionRange.x() <= 0 || unionRange.y() >= viewport.getWidth()-1;

			if (squareFits || bboxClipped || viewportClipped)
				return true;
		}
	}

	if (--logFloodCounter >= 0)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Missing " << expectedPointSize << "x" << expectedPointSize << " point near " << pointPos << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
			<< tcu::TestLog::EndMessage;
	}
	return false;
}

tcu::IVec2 PointRenderCase::scanPointWidthAt (const tcu::IVec2& pointPos, const tcu::Surface& viewport, int expectedPointSize, int componentNdx) const
{
	int minX = pointPos.x();
	int maxX = pointPos.x();

	// search horizontally for a point edges
	for (int x = pointPos.x()-1; x >= 0; --x)
	{
		if (viewport.getPixel(x, pointPos.y()).toIVec()[componentNdx] == 0)
			break;

		// no need to go further than point width
		if (pointPos.x() - x > expectedPointSize)
			break;

		minX = x;
	}
	for (int x = pointPos.x()+1; x < viewport.getWidth(); ++x)
	{
		if (viewport.getPixel(x, pointPos.y()).toIVec()[componentNdx] == 0)
			break;

		// no need to go further than point width
		if (x - pointPos.x() > expectedPointSize)
			break;

		maxX = x;
	}

	return tcu::IVec2(minX, maxX);
}

class BlitFboCase : public TestCase
{
public:
	enum RenderTarget
	{
		TARGET_DEFAULT = 0,
		TARGET_FBO,

		TARGET_LAST
	};

							BlitFboCase						(Context& context, const char* name, const char* description, RenderTarget src, RenderTarget dst);
							~BlitFboCase					(void);

private:
	enum
	{
		FBO_SIZE = 256,
	};

	struct BlitArgs
	{
		tcu::IVec4	src;
		tcu::IVec4	dst;
		tcu::Vec4	bboxMin;
		tcu::Vec4	bboxMax;
		bool		linear;
	};

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

	void							fillSourceWithPattern	(void);
	bool							verifyImage				(const BlitArgs& args);

	const RenderTarget				m_src;
	const RenderTarget				m_dst;

	std::vector<BlitArgs>			m_iterations;
	int								m_iteration;
	de::MovePtr<glu::Framebuffer>	m_srcFbo;
	de::MovePtr<glu::Framebuffer>	m_dstFbo;
	de::MovePtr<glu::Renderbuffer>	m_srcRbo;
	de::MovePtr<glu::Renderbuffer>	m_dstRbo;
	de::MovePtr<glu::ShaderProgram>	m_program;
	de::MovePtr<glu::Buffer>	m_vbo;
	glw::GLuint			m_vao;
};

BlitFboCase::BlitFboCase (Context& context, const char* name, const char* description, RenderTarget src, RenderTarget dst)
	: TestCase		(context, name, description)
	, m_src			(src)
	, m_dst			(dst)
	, m_iteration	(0)
	, m_vao		(0)
{
	DE_ASSERT(src < TARGET_LAST);
	DE_ASSERT(dst < TARGET_LAST);
}

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

void BlitFboCase::init (void)
{
	const int				numIterations			= 12;
	const bool				defaultFBMultisampled	= (m_context.getRenderTarget().getNumSamples() > 1);
	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
	de::Random				rnd						(0xABC123);

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Using BlitFramebuffer to blit area from "
			<< ((m_src == TARGET_DEFAULT) ? ("default fb") : ("fbo"))
			<< " to "
			<< ((m_dst == TARGET_DEFAULT) ? ("default fb") : ("fbo"))
			<< ".\n"
		<< "Varying blit arguments and primitive bounding box between iterations.\n"
		<< "Expecting bounding box to have no effect on blitting.\n"
		<< "Source framebuffer is filled with green-yellow grid.\n"
		<< tcu::TestLog::EndMessage;

	if (!boundingBoxSupported(m_context))
		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");

	if (m_dst == TARGET_DEFAULT && defaultFBMultisampled)
		throw tcu::NotSupportedError("Test requires non-multisampled default framebuffer");

	// resources

	if (m_src == TARGET_FBO)
	{
		m_srcRbo = de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(m_context.getRenderContext()));
		gl.bindRenderbuffer(GL_RENDERBUFFER, **m_srcRbo);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, FBO_SIZE, FBO_SIZE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "src rbo");

		m_srcFbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
		gl.bindFramebuffer(GL_FRAMEBUFFER, **m_srcFbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **m_srcRbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "src fbo");
	}

	if (m_dst == TARGET_FBO)
	{
		m_dstRbo = de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(m_context.getRenderContext()));
		gl.bindRenderbuffer(GL_RENDERBUFFER, **m_dstRbo);
		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, FBO_SIZE, FBO_SIZE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "dst rbo");

		m_dstFbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
		gl.bindFramebuffer(GL_FRAMEBUFFER, **m_dstFbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **m_dstRbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "dst fbo");
	}

	{
		const char* const vertexSource =	"${GLSL_VERSION_DECL}\n"
													"in highp vec4 a_position;\n"
													"out highp vec4 v_position;\n"
													"void main()\n"
													"{\n"
													"	gl_Position = a_position;\n"
													"	v_position = a_position;\n"
													"}\n";
		const char* const fragmentSource =	"${GLSL_VERSION_DECL}\n"
													"in mediump vec4 v_position;\n"
													"layout(location=0) out mediump vec4 dEQP_FragColor;\n"
													"void main()\n"
													"{\n"
													"	const mediump vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
													"	const mediump vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
													"	dEQP_FragColor = (step(0.1, mod(v_position.x, 0.2)) == step(0.1, mod(v_position.y, 0.2))) ? (green) : (yellow);\n"
													"}\n";

		m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, vertexSource)) << glu::FragmentSource(specializeShader(m_context, fragmentSource))));

		if (!m_program->isOk())
		{
			m_testCtx.getLog() << *m_program;
			throw tcu::TestError("failed to build program");
		}
	}


	// Generate VAO for desktop OpenGL
	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.genVertexArrays(1, &m_vao);
		gl.bindVertexArray(m_vao);
	}

	{
		static const tcu::Vec4 s_quadCoords[] =
		{
			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),
		};

		m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));

		gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
		gl.bufferData(GL_ARRAY_BUFFER, sizeof(s_quadCoords), s_quadCoords, GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "set buf");
	}

	// gen iterations

	{
		const tcu::IVec2 srcSize = (m_src == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));
		const tcu::IVec2 dstSize = (m_dst == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "srcSize = " << srcSize << "\n"
			<< "dstSize = " << dstSize << "\n"
			<< tcu::TestLog::EndMessage;

		for (int ndx = 0; ndx < numIterations; ++ndx)
		{
			BlitArgs args;

			if (m_src == TARGET_DEFAULT && defaultFBMultisampled)
			{
				const tcu::IVec2	unionSize	= tcu::IVec2(de::min(srcSize.x(), dstSize.x()), de::min(srcSize.y(), dstSize.y()));
				const int			srcWidth	= rnd.getInt(1, unionSize.x());
				const int			srcHeight	= rnd.getInt(1, unionSize.y());
				const int			srcX		= rnd.getInt(0, unionSize.x() - srcWidth);
				const int			srcY		= rnd.getInt(0, unionSize.y() - srcHeight);

				args.src.x() = srcX;
				args.src.y() = srcY;
				args.src.z() = srcX + srcWidth;
				args.src.w() = srcY + srcHeight;

				args.dst = args.src;
			}
			else
			{
				const int	srcWidth	= rnd.getInt(1, srcSize.x());
				const int	srcHeight	= rnd.getInt(1, srcSize.y());
				const int	srcX		= rnd.getInt(0, srcSize.x() - srcWidth);
				const int	srcY		= rnd.getInt(0, srcSize.y() - srcHeight);
				const int	dstWidth	= rnd.getInt(1, dstSize.x());
				const int	dstHeight	= rnd.getInt(1, dstSize.y());
				const int	dstX		= rnd.getInt(-(dstWidth / 2), dstSize.x() - (dstWidth+1) / 2);		// allow dst go out of bounds
				const int	dstY		= rnd.getInt(-(dstHeight / 2), dstSize.y() - (dstHeight+1)  / 2);

				args.src.x() = srcX;
				args.src.y() = srcY;
				args.src.z() = srcX + srcWidth;
				args.src.w() = srcY + srcHeight;
				args.dst.x() = dstX;
				args.dst.y() = dstY;
				args.dst.z() = dstX + dstWidth;
				args.dst.w() = dstY + dstHeight;
			}

			args.bboxMin.x() = rnd.getFloat(-1.1f, 1.1f);
			args.bboxMin.y() = rnd.getFloat(-1.1f, 1.1f);
			args.bboxMin.z() = rnd.getFloat(-1.1f, 1.1f);
			args.bboxMin.w() = rnd.getFloat( 0.9f, 1.1f);

			args.bboxMax.x() = rnd.getFloat(-1.1f, 1.1f);
			args.bboxMax.y() = rnd.getFloat(-1.1f, 1.1f);
			args.bboxMax.z() = rnd.getFloat(-1.1f, 1.1f);
			args.bboxMax.w() = rnd.getFloat( 0.9f, 1.1f);

			if (args.bboxMin.x() / args.bboxMin.w() > args.bboxMax.x() / args.bboxMax.w())
				std::swap(args.bboxMin.x(), args.bboxMax.x());
			if (args.bboxMin.y() / args.bboxMin.w() > args.bboxMax.y() / args.bboxMax.w())
				std::swap(args.bboxMin.y(), args.bboxMax.y());
			if (args.bboxMin.z() / args.bboxMin.w() > args.bboxMax.z() / args.bboxMax.w())
				std::swap(args.bboxMin.z(), args.bboxMax.z());

			args.linear = rnd.getBool();

			m_iterations.push_back(args);
		}
	}
}

void BlitFboCase::deinit (void)
{
	m_srcFbo.clear();
	m_srcRbo.clear();
	m_dstFbo.clear();
	m_dstRbo.clear();
	m_program.clear();
	m_vbo.clear();

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

BlitFboCase::IterateResult BlitFboCase::iterate (void)
{
	const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Iteration" + de::toString(m_iteration), "Iteration " + de::toString(m_iteration+1) + " / " + de::toString((int)m_iterations.size()));
	const BlitArgs&				blitCfg		= m_iterations[m_iteration];
	const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();

	if (m_iteration == 0)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	// fill source with test pattern. Default fb must be filled for each iteration because contents might not survive the swap
	if (m_src == TARGET_DEFAULT || m_iteration == 0)
		fillSourceWithPattern();

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Set bounding box:\n"
		<< "\tmin:" << blitCfg.bboxMin << "\n"
		<< "\tmax:" << blitCfg.bboxMax << "\n"
		<< "Blit:\n"
		<<	"\tsrc: " << blitCfg.src << "\n"
		<<	"\tdst: " << blitCfg.dst << "\n"
		<<	"\tfilter: " << ((blitCfg.linear) ? ("linear") : ("nearest"))
		<< tcu::TestLog::EndMessage;

	auto boundingBoxFunc = getBoundingBoxFunction(m_context);

	boundingBoxFunc(blitCfg.bboxMin.x(), blitCfg.bboxMin.y(), blitCfg.bboxMin.z(), blitCfg.bboxMin.w(),
			blitCfg.bboxMax.x(), blitCfg.bboxMax.y(), blitCfg.bboxMax.z(), blitCfg.bboxMax.w());
	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, (m_dst == TARGET_FBO) ? (**m_dstFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, (m_src == TARGET_FBO) ? (**m_srcFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
	gl.blitFramebuffer(blitCfg.src.x(), blitCfg.src.y(), blitCfg.src.z(), blitCfg.src.w(),
					   blitCfg.dst.x(), blitCfg.dst.y(), blitCfg.dst.z(), blitCfg.dst.w(),
					   GL_COLOR_BUFFER_BIT,
					   ((blitCfg.linear) ? (GL_LINEAR) : (GL_NEAREST)));
	GLU_EXPECT_NO_ERROR(gl.getError(), "blit");

	if (!verifyImage(blitCfg))
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected blit result");

	return (++m_iteration == (int)m_iterations.size()) ? (STOP) : (CONTINUE);
}

bool BlitFboCase::verifyImage (const BlitArgs& args)
{
	const int				colorThreshold	= 4; //!< this test case is not about how color is preserved, allow almost anything
	const tcu::IVec2		dstSize			= (m_dst == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	tcu::Surface			viewport		(dstSize.x(), dstSize.y());
	tcu::Surface			errorMask		(dstSize.x(), dstSize.y());
	bool					anyError		= false;

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

	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, (m_dst == TARGET_FBO) ? (**m_dstFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
	glu::readPixels(m_context.getRenderContext(), 0, 0, viewport.getAccess());

	tcu::clear(errorMask.getAccess(), tcu::IVec4(0, 0, 0, 255));

	for (int y = 0; y < dstSize.y(); ++y)
	for (int x = 0; x < dstSize.x(); ++x)
	{
		const tcu::RGBA color	= viewport.getPixel(x, y);
		const bool		inside	= (x >= args.dst.x() && x < args.dst.z() && y >= args.dst.y() && y < args.dst.w());
		const bool		error	= (inside) ? (color.getGreen() < 255 - colorThreshold || color.getBlue() > colorThreshold)
										   : (color.getRed() > colorThreshold || color.getGreen() > colorThreshold || color.getBlue() > colorThreshold);

		if (error)
		{
			anyError = true;
			errorMask.setPixel(x, y, tcu::RGBA::red());
		}
	}

	if (anyError)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
			<< tcu::TestLog::EndImageSet;
		return false;
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Result image ok."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
			<< tcu::TestLog::EndImageSet;
		return true;
	}
}

void BlitFboCase::fillSourceWithPattern (void)
{
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	const tcu::IVec2		srcSize		= (m_src == TARGET_DEFAULT) ? (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) : (tcu::IVec2(FBO_SIZE, FBO_SIZE));
	const int				posLocation	= gl.getAttribLocation(m_program->getProgram(), "a_position");

	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, (m_src == TARGET_FBO) ? (**m_srcFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
	gl.viewport(0, 0, srcSize.x(), srcSize.y());
	gl.useProgram(m_program->getProgram());

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

	gl.enableVertexAttribArray(posLocation);
	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 4 * (int)sizeof(float), NULL);
	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
}

class DepthDrawCase : public TestCase
{
public:
	enum DepthType
	{
		DEPTH_BUILTIN = 0,
		DEPTH_USER_DEFINED,

		DEPTH_LAST
	};
	enum BBoxState
	{
		STATE_GLOBAL = 0,
		STATE_PER_PRIMITIVE,

		STATE_LAST
	};
	enum BBoxSize
	{
		BBOX_EQUAL = 0,
		BBOX_LARGER,

		BBOX_LAST
	};

									DepthDrawCase					(Context& context, const char* name, const char* description, DepthType depthType, BBoxState state, BBoxSize bboxSize);
									~DepthDrawCase					(void);

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

	std::string						genVertexSource					(void) const;
	std::string						genFragmentSource				(void) const;
	std::string						genTessellationControlSource	(void) const;
	std::string						genTessellationEvaluationSource	(void) const;
	void							generateAttributeData			(std::vector<tcu::Vec4>& data) const;
	bool							verifyImage						(const tcu::Surface& viewport) const;

	enum
	{
		RENDER_AREA_SIZE = 256,
	};

	struct LayerInfo
	{
		float		zOffset;
		float		zScale;
		tcu::Vec4	color1;
		tcu::Vec4	color2;
	};

	const int						m_numLayers;
	const int						m_gridSize;

	const DepthType					m_depthType;
	const BBoxState					m_state;
	const BBoxSize					m_bboxSize;

	de::MovePtr<glu::ShaderProgram>	m_program;
	de::MovePtr<glu::Buffer>		m_vbo;
	glw::GLuint				m_vao;
	std::vector<LayerInfo>			m_layers;
};

DepthDrawCase::DepthDrawCase (Context& context, const char* name, const char* description, DepthType depthType, BBoxState state, BBoxSize bboxSize)
	: TestCase		(context, name, description)
	, m_numLayers	(14)
	, m_gridSize	(24)
	, m_depthType	(depthType)
	, m_state		(state)
	, m_bboxSize	(bboxSize)
	, m_vao		(0)
{
	DE_ASSERT(depthType < DEPTH_LAST);
	DE_ASSERT(state < STATE_LAST);
	DE_ASSERT(bboxSize < BBOX_LAST);
}

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

void DepthDrawCase::init (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	const bool		hasES32OrGL45			= supportsES32OrGL45(m_context);

	// requirements
	if (!boundingBoxSupported(m_context))
		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
	if (m_state == STATE_PER_PRIMITIVE && !hasES32OrGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	if (m_context.getRenderTarget().getDepthBits() == 0)
		throw tcu::NotSupportedError("Test requires depth buffer");
	if (m_context.getRenderTarget().getWidth() < RENDER_AREA_SIZE || m_context.getRenderTarget().getHeight() < RENDER_AREA_SIZE)
		throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_AREA_SIZE) + "x" + de::toString<int>(RENDER_AREA_SIZE) + " viewport");

	// log
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Rendering multiple triangle grids with with different z coordinates.\n"
		<< "Topmost grid is green-yellow, other grids are blue-red.\n"
		<< "Expecting only the green-yellow grid to be visible.\n"
		<< "Setting primitive bounding box "
			<< ((m_bboxSize == BBOX_EQUAL) ? ("to exactly cover") : ("to cover"))
			<< ((m_state == STATE_GLOBAL) ? (" each grid") : (" each triangle"))
			<< ((m_bboxSize == BBOX_EQUAL) ? (".") : (" and include some padding."))
			<< "\n"
		<< "Set bounding box using "
			<< ((m_state == STATE_GLOBAL) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
			<< "\n"
		<< ((m_depthType == DEPTH_USER_DEFINED) ? ("Fragment depth is set in the fragment shader") : (""))
		<< tcu::TestLog::EndMessage;

	// resources

	{
		glu::ProgramSources sources;
		sources << glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()));
		sources << glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()));

		if (m_state == STATE_PER_PRIMITIVE)
			sources << glu::TessellationControlSource(specializeShader(m_context, genTessellationControlSource().c_str()))
					<< glu::TessellationEvaluationSource(specializeShader(m_context, genTessellationEvaluationSource().c_str()));

		m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources));
		GLU_EXPECT_NO_ERROR(gl.getError(), "build program");

		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "ShaderProgram", "Shader program");
			m_testCtx.getLog() << *m_program;
		}

		if (!m_program->isOk())
			throw tcu::TestError("failed to build program");
	}

	// Generate VAO for desktop OpenGL
	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.genVertexArrays(1, &m_vao);
		gl.bindVertexArray(m_vao);
	}

	{
		std::vector<tcu::Vec4> data;

		generateAttributeData(data);

		m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
		gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
		gl.bufferData(GL_ARRAY_BUFFER, (int)(sizeof(tcu::Vec4) * data.size()), &data[0], GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "buf upload");
	}

	// gen layers
	{
		de::Random rnd(0x12345);

		m_layers.resize(m_numLayers);
		for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
		{
			m_layers[layerNdx].zOffset	= ((float)layerNdx / (float)m_numLayers) * 2.0f - 1.0f;
			m_layers[layerNdx].zScale	= (2.0f / (float)m_numLayers);
			m_layers[layerNdx].color1	= (layerNdx == 0) ? (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) : (tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
			m_layers[layerNdx].color2	= (layerNdx == 0) ? (tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f)) : (tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
		}
		rnd.shuffle(m_layers.begin(), m_layers.end());
	}
}

void DepthDrawCase::deinit (void)
{
	m_program.clear();
	m_vbo.clear();

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

DepthDrawCase::IterateResult DepthDrawCase::iterate (void)
{
	const bool				hasTessellation		= (m_state == STATE_PER_PRIMITIVE);
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const glw::GLint		posLocation			= gl.getAttribLocation(m_program->getProgram(), "a_position");
	const glw::GLint		colLocation			= gl.getAttribLocation(m_program->getProgram(), "a_colorMix");
	const glw::GLint		depthBiasLocation	= gl.getUniformLocation(m_program->getProgram(), "u_depthBias");
	const glw::GLint		depthScaleLocation	= gl.getUniformLocation(m_program->getProgram(), "u_depthScale");
	const glw::GLint		color1Location		= gl.getUniformLocation(m_program->getProgram(), "u_color1");
	const glw::GLint		color2Location		= gl.getUniformLocation(m_program->getProgram(), "u_color2");

	tcu::Surface			viewport			(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	de::Random				rnd					(0x213237);

	TCU_CHECK(posLocation != -1);
	TCU_CHECK(colLocation != -1);
	TCU_CHECK(depthBiasLocation != -1);
	TCU_CHECK(depthScaleLocation != -1);
	TCU_CHECK(color1Location != -1);
	TCU_CHECK(color2Location != -1);

	gl.viewport(0, 0, RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clearDepthf(1.0f);
	gl.depthFunc(GL_LESS);
	gl.enable(GL_DEPTH_TEST);
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "setup viewport");

	auto boundingBoxFunc = getBoundingBoxFunction(m_context);

	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, (int)(8 * sizeof(float)), glu::BufferOffsetAsPointer(0 * sizeof(float)));
	gl.vertexAttribPointer(colLocation, 4, GL_FLOAT, GL_FALSE, (int)(8 * sizeof(float)), glu::BufferOffsetAsPointer(4 * sizeof(float)));
	gl.enableVertexAttribArray(posLocation);
	gl.enableVertexAttribArray(colLocation);
	gl.useProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "setup va");

	if (hasTessellation)
		gl.patchParameteri(GL_PATCH_VERTICES, 3);

	for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
	{
		gl.uniform1f(depthBiasLocation, m_layers[layerNdx].zOffset);
		gl.uniform1f(depthScaleLocation, m_layers[layerNdx].zScale);
		gl.uniform4fv(color1Location, 1, m_layers[layerNdx].color1.getPtr());
		gl.uniform4fv(color2Location, 1, m_layers[layerNdx].color2.getPtr());

		if (m_state == STATE_GLOBAL)
		{
			const float negPadding = (m_bboxSize == BBOX_EQUAL) ? (0.0f) : (rnd.getFloat() * 0.3f);
			const float posPadding = (m_bboxSize == BBOX_EQUAL) ? (0.0f) : (rnd.getFloat() * 0.3f);

			boundingBoxFunc(-1.0f, -1.0f, m_layers[layerNdx].zOffset - negPadding, 1.0f,
					1.0f,  1.0f, (m_layers[layerNdx].zOffset + m_layers[layerNdx].zScale + posPadding), 1.0f);
		}

		gl.drawArrays((hasTessellation) ? (GL_PATCHES) : (GL_TRIANGLES), 0, m_gridSize * m_gridSize * 6);
	}

	glu::readPixels(m_context.getRenderContext(), 0, 0, viewport.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "render and read");

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

	return STOP;
}

std::string DepthDrawCase::genVertexSource (void) const
{
	const bool			hasTessellation	= (m_state == STATE_PER_PRIMITIVE);
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in highp vec4 a_position;\n"
			"in highp vec4 a_colorMix;\n"
			"out highp vec4 vtx_colorMix;\n";

	if (!hasTessellation && m_depthType == DEPTH_USER_DEFINED)
		buf << "out highp float v_fragDepth;\n";

	if (!hasTessellation)
		buf <<	"uniform highp float u_depthBias;\n"
				"uniform highp float u_depthScale;\n";

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

	if (hasTessellation)
		buf << "	gl_Position = a_position;\n";
	else if (m_depthType == DEPTH_USER_DEFINED)
		buf <<	"	highp float dummyZ = a_position.z;\n"
				"	highp float writtenZ = a_position.w;\n"
				"	gl_Position = vec4(a_position.xy, dummyZ, 1.0);\n"
				"	v_fragDepth = writtenZ * u_depthScale + u_depthBias;\n";
	else
		buf <<	"	highp float writtenZ = a_position.w;\n"
				"	gl_Position = vec4(a_position.xy, writtenZ * u_depthScale + u_depthBias, 1.0);\n";

	buf <<	"	vtx_colorMix = a_colorMix;\n"
			"}\n";

	return buf.str();
}

std::string DepthDrawCase::genFragmentSource (void) const
{
	const bool			hasTessellation	= (m_state == STATE_PER_PRIMITIVE);
	const char* const	colorMixName	= (hasTessellation) ? ("tess_eval_colorMix") : ("vtx_colorMix");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in mediump vec4 " << colorMixName << ";\n";

	if (m_depthType == DEPTH_USER_DEFINED)
		buf << "in mediump float v_fragDepth;\n";

	buf <<	"layout(location = 0) out mediump vec4 o_color;\n"
			"uniform highp vec4 u_color1;\n"
			"uniform highp vec4 u_color2;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	o_color = mix(u_color1, u_color2, " << colorMixName << ");\n";

	if (m_depthType == DEPTH_USER_DEFINED)
		buf << "	gl_FragDepth = v_fragDepth * 0.5 + 0.5;\n";

	buf <<	"}\n";

	return buf.str();
}

std::string DepthDrawCase::genTessellationControlSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
			"layout(vertices=3) out;\n"
			"\n"
			"uniform highp float u_depthBias;\n"
			"uniform highp float u_depthScale;\n"
			"\n"
			"in highp vec4 vtx_colorMix[];\n"
			"out highp vec4 tess_ctrl_colorMix[];\n"
			"\n"
			"void main()\n"
			"{\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
			"	tess_ctrl_colorMix[gl_InvocationID] = vtx_colorMix[0];\n"
			"\n"
			"	gl_TessLevelOuter[0] = 2.8;\n"
			"	gl_TessLevelOuter[1] = 2.8;\n"
			"	gl_TessLevelOuter[2] = 2.8;\n"
			"	gl_TessLevelInner[0] = 2.8;\n"
			"\n"
			"	// real Z stored in w component\n"
			"	highp vec4 minBound = vec4(min(min(vec3(gl_in[0].gl_Position.xy, gl_in[0].gl_Position.w * u_depthScale + u_depthBias),\n"
			"	                                   vec3(gl_in[1].gl_Position.xy, gl_in[1].gl_Position.w * u_depthScale + u_depthBias)),\n"
			"	                               vec3(gl_in[2].gl_Position.xy, gl_in[2].gl_Position.w * u_depthScale + u_depthBias)), 1.0);\n"
			"	highp vec4 maxBound = vec4(max(max(vec3(gl_in[0].gl_Position.xy, gl_in[0].gl_Position.w * u_depthScale + u_depthBias),\n"
			"	                                   vec3(gl_in[1].gl_Position.xy, gl_in[1].gl_Position.w * u_depthScale + u_depthBias)),\n"
			"	                               vec3(gl_in[2].gl_Position.xy, gl_in[2].gl_Position.w * u_depthScale + u_depthBias)), 1.0);\n";

	if (m_bboxSize == BBOX_EQUAL)
		buf <<	"	${PRIM_GL_BOUNDING_BOX}[0] = minBound;\n"
				"	${PRIM_GL_BOUNDING_BOX}[1] = maxBound;\n";
	else
		buf <<	"	highp float nedPadding = mod(gl_in[0].gl_Position.z, 0.3);\n"
				"	highp float posPadding = mod(gl_in[1].gl_Position.z, 0.3);\n"
				"	${PRIM_GL_BOUNDING_BOX}[0] = minBound - vec4(0.0, 0.0, nedPadding, 0.0);\n"
				"	${PRIM_GL_BOUNDING_BOX}[1] = maxBound + vec4(0.0, 0.0, posPadding, 0.0);\n";

	buf <<	"}\n";

	return buf.str();
}

std::string DepthDrawCase::genTessellationEvaluationSource (void) const
{
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"${GPU_SHADER5_REQUIRE}\n"
			"layout(triangles) in;\n"
			"\n"
			"in highp vec4 tess_ctrl_colorMix[];\n"
			"out highp vec4 tess_eval_colorMix;\n";

	if (m_depthType == DEPTH_USER_DEFINED)
		buf << "out highp float v_fragDepth;\n";

	buf <<	"uniform highp float u_depthBias;\n"
			"uniform highp float u_depthScale;\n"
			"\n"
			"precise gl_Position;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	highp vec4 tessellatedPos = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n";

	if (m_depthType == DEPTH_USER_DEFINED)
		buf <<	"	highp float dummyZ = tessellatedPos.z;\n"
				"	highp float writtenZ = tessellatedPos.w;\n"
				"	gl_Position = vec4(tessellatedPos.xy, dummyZ, 1.0);\n"
				"	v_fragDepth = writtenZ * u_depthScale + u_depthBias;\n";
	else
		buf <<	"	highp float writtenZ = tessellatedPos.w;\n"
				"	gl_Position = vec4(tessellatedPos.xy, writtenZ * u_depthScale + u_depthBias, 1.0);\n";

	buf <<	"	tess_eval_colorMix = tess_ctrl_colorMix[0];\n"
			"}\n";

	return buf.str();
}

void DepthDrawCase::generateAttributeData (std::vector<tcu::Vec4>& data) const
{
	const tcu::Vec4		color1				(0.0f, 0.0f, 0.0f, 0.0f); // mix weights
	const tcu::Vec4		color2				(1.0f, 1.0f, 1.0f, 1.0f);
	std::vector<int>	cellOrder			(m_gridSize * m_gridSize);
	de::Random			rnd					(0xAB54321);

	// generate grid with cells in random order
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
		cellOrder[ndx] = ndx;
	rnd.shuffle(cellOrder.begin(), cellOrder.end());

	data.resize(m_gridSize * m_gridSize * 6 * 2);
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
	{
		const int			cellNdx		= cellOrder[ndx];
		const int			cellX		= cellNdx % m_gridSize;
		const int			cellY		= cellNdx / m_gridSize;
		const tcu::Vec4&	cellColor	= ((cellX+cellY)%2 == 0) ? (color1) : (color2);

		data[ndx * 6 * 2 +  0] = tcu::Vec4(float(cellX+0) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  1] = cellColor;
		data[ndx * 6 * 2 +  2] = tcu::Vec4(float(cellX+1) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  3] = cellColor;
		data[ndx * 6 * 2 +  4] = tcu::Vec4(float(cellX+0) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  5] = cellColor;
		data[ndx * 6 * 2 +  6] = tcu::Vec4(float(cellX+0) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  7] = cellColor;
		data[ndx * 6 * 2 +  8] = tcu::Vec4(float(cellX+1) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 +  9] = cellColor;
		data[ndx * 6 * 2 + 10] = tcu::Vec4(float(cellX+1) / float(m_gridSize) * 2.0f - 1.0f, float(cellY+1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);	data[ndx * 6 * 2 + 11] = cellColor;

		// Fill Z with random values (fake Z)
		for (int vtxNdx = 0; vtxNdx < 6; ++vtxNdx)
			data[ndx * 6 * 2 + 2*vtxNdx].z() = rnd.getFloat(0.0f, 1.0);

		// Fill W with other random values (written Z)
		for (int vtxNdx = 0; vtxNdx < 6; ++vtxNdx)
			data[ndx * 6 * 2 + 2*vtxNdx].w() = rnd.getFloat(0.0f, 1.0);
	}
}

bool DepthDrawCase::verifyImage (const tcu::Surface& viewport) const
{
	tcu::Surface	errorMask	(viewport.getWidth(), viewport.getHeight());
	bool			anyError	= false;

	tcu::clear(errorMask.getAccess(), tcu::IVec4(0,0,0,255));

	for (int y = 0; y < viewport.getHeight(); ++y)
	for (int x = 0; x < viewport.getWidth(); ++x)
	{
		const tcu::RGBA	pixel		= viewport.getPixel(x, y);
		bool			error		= false;

		// expect green, yellow or a combination of these
		if (pixel.getGreen() != 255 || pixel.getBlue() != 0)
			error = true;

		if (error)
		{
			errorMask.setPixel(x, y, tcu::RGBA::red());
			anyError = true;
		}
	}

	if (anyError)
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
			<< tcu::TestLog::EndImageSet;
	else
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Result image ok."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
			<< tcu::TestLog::EndImageSet;

	return !anyError;
}

class ClearCase : public TestCase
{
public:
	enum
	{
		SCISSOR_CLEAR_BIT		= 1 << 0,
		DRAW_TRIANGLE_BIT		= 1 << 1,
		PER_PRIMITIVE_BBOX_BIT	= 1 << 2,
		FULLSCREEN_SCISSOR_BIT	= 1 << 3,
	};

									ClearCase						(Context& context, const char* name, const char* description, deUint32 flags);
									~ClearCase						(void);

private:
	struct DrawObject
	{
		int firstNdx;
		int numVertices;
	};

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

	void							createVbo						(void);
	void							createProgram					(void);
	void							renderTo						(tcu::Surface& dst, bool useBBox);
	bool							verifyImagesEqual				(const tcu::PixelBufferAccess& withoutBBox, const tcu::PixelBufferAccess& withBBox);
	bool							verifyImageResultValid			(const tcu::PixelBufferAccess& result);

	std::string						genVertexSource					(void) const;
	std::string						genFragmentSource				(void) const;
	std::string						genTessellationControlSource	(bool setBBox) const;
	std::string						genTessellationEvaluationSource	(void) const;

	const bool						m_scissoredClear;
	const bool						m_fullscreenScissor;
	const bool						m_drawTriangles;
	const bool						m_useGlobalState;

	de::MovePtr<glu::Buffer>		m_vbo;
	de::MovePtr<glu::ShaderProgram>	m_perPrimitiveProgram;
	de::MovePtr<glu::ShaderProgram>	m_basicProgram;
	std::vector<DrawObject>			m_drawObjects;
	std::vector<tcu::Vec4>			m_objectVertices;
};

ClearCase::ClearCase (Context& context, const char* name, const char* description, deUint32 flags)
	: TestCase				(context, name, description)
	, m_scissoredClear		((flags & SCISSOR_CLEAR_BIT) != 0)
	, m_fullscreenScissor	((flags & FULLSCREEN_SCISSOR_BIT) != 0)
	, m_drawTriangles		((flags & DRAW_TRIANGLE_BIT) != 0)
	, m_useGlobalState		((flags & PER_PRIMITIVE_BBOX_BIT) == 0)
{
	DE_ASSERT(m_useGlobalState || m_drawTriangles); // per-triangle bbox requires triangles
	DE_ASSERT(!m_fullscreenScissor || m_scissoredClear); // fullscreenScissor requires scissoredClear
}

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

void ClearCase::init (void)
{
	const bool hasES32OrGL45 = supportsES32OrGL45(m_context);

	if (!boundingBoxSupported(m_context))
		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
	if (m_drawTriangles && !hasES32OrGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Doing multiple"
			<< ((m_scissoredClear) ? (" scissored") : (""))
			<< " color buffer clears"
			<< ((m_drawTriangles) ? (" and drawing some geometry between them") : (""))
			<< ".\n"
		<< ((m_scissoredClear && m_fullscreenScissor) ? ("Setting scissor area to cover entire viewport.\n") : (""))
		<< "Rendering with and without setting the bounding box.\n"
		<< "Expecting bounding box to have no effect on clears (i.e. results are constant).\n"
		<< "Set bounding box using "
			<< ((m_useGlobalState) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
			<< ".\n"
		<< "Clear color is green with yellowish shades.\n"
		<< ((m_drawTriangles) ? ("Primitive color is yellow with greenish shades.\n") : (""))
		<< tcu::TestLog::EndMessage;

	if (m_drawTriangles)
	{
		createVbo();
		createProgram();
	}
}

void ClearCase::deinit (void)
{
	m_vbo.clear();
	m_perPrimitiveProgram.clear();
	m_basicProgram.clear();
	m_drawObjects = std::vector<DrawObject>();
	m_objectVertices = std::vector<tcu::Vec4>();
}

ClearCase::IterateResult ClearCase::iterate (void)
{
	const tcu::IVec2	renderTargetSize	(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
	tcu::Surface		resultWithoutBBox	(renderTargetSize.x(), renderTargetSize.y());
	tcu::Surface		resultWithBBox		(renderTargetSize.x(), renderTargetSize.y());

	// render with and without bbox set
	for (int passNdx = 0; passNdx < 2; ++passNdx)
	{
		const bool		useBBox			= (passNdx == 1);
		tcu::Surface&	destination		= (useBBox) ? (resultWithBBox) : (resultWithoutBBox);

		renderTo(destination, useBBox);
	}

	// Verify images are equal and that the image does not contain (trivially detectable) garbage

	if (!verifyImagesEqual(resultWithoutBBox.getAccess(), resultWithBBox.getAccess()))
	{
		// verifyImagesEqual will print out the image and error mask
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
	}
	else if (!verifyImageResultValid(resultWithBBox.getAccess()))
	{
		// verifyImageResultValid will print out the image and error mask
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image comparison passed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Result", "Result", resultWithBBox.getAccess())
			<< tcu::TestLog::EndImageSet;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}

	return STOP;
}

void ClearCase::createVbo (void)
{
	const int				numObjects	= 16;
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	de::Random				rnd			(deStringHash(getName()));

	m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));

	for (int objectNdx = 0; objectNdx < numObjects; ++objectNdx)
	{
		const int	numTriangles	= rnd.getInt(1, 4);
		const float	minX			= rnd.getFloat(-1.2f, 0.8f);
		const float	minY			= rnd.getFloat(-1.2f, 0.8f);
		const float	maxX			= minX + rnd.getFloat(0.2f, 1.0f);
		const float	maxY			= minY + rnd.getFloat(0.2f, 1.0f);

		DrawObject	drawObject;
		drawObject.firstNdx = (int)m_objectVertices.size();
		drawObject.numVertices = numTriangles * 3;

		m_drawObjects.push_back(drawObject);

		for (int triangleNdx = 0; triangleNdx < numTriangles; ++triangleNdx)
		for (int vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
		{
			const float posX = rnd.getFloat(minX, maxX);
			const float posY = rnd.getFloat(minY, maxY);
			const float posZ = rnd.getFloat(-0.7f, 0.7f);
			const float posW = rnd.getFloat(0.9f, 1.1f);

			m_objectVertices.push_back(tcu::Vec4(posX, posY, posZ, posW));
		}
	}

	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
	gl.bufferData(GL_ARRAY_BUFFER, (int)(m_objectVertices.size() * sizeof(tcu::Vec4)), &m_objectVertices[0], GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "buffer upload");
}

void ClearCase::createProgram (void)
{
	m_basicProgram = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(),
																			glu::ProgramSources()
																				<< glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()))
																				<< glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()))
																				<< glu::TessellationControlSource(specializeShader(m_context, genTessellationControlSource(false).c_str()))
																				<< glu::TessellationEvaluationSource(specializeShader(m_context, genTessellationEvaluationSource().c_str()))));

	m_testCtx.getLog()
		<< tcu::TestLog::Section("Program", "Shader program")
		<< *m_basicProgram
		<< tcu::TestLog::EndSection;

	if (!m_basicProgram->isOk())
		throw tcu::TestError("shader build failed");

	if (!m_useGlobalState)
	{
		m_perPrimitiveProgram = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(),
																					   glu::ProgramSources()
																							<< glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()))
																							<< glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()))
																							<< glu::TessellationControlSource(specializeShader(m_context, genTessellationControlSource(true).c_str()))
																							<< glu::TessellationEvaluationSource(specializeShader(m_context, genTessellationEvaluationSource().c_str()))));

		m_testCtx.getLog()
			<< tcu::TestLog::Section("PerPrimitiveProgram", "Shader program that sets the bounding box")
			<< *m_perPrimitiveProgram
			<< tcu::TestLog::EndSection;

		if (!m_perPrimitiveProgram->isOk())
			throw tcu::TestError("shader build failed");
	}
}

void ClearCase::renderTo (tcu::Surface& dst, bool useBBox)
{
	const int				numOps				= 45;
	const tcu::Vec4			yellow				(1.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4			green				(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::IVec2		renderTargetSize	(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	de::Random				rnd					(deStringHash(getName()));
	glu::VertexArray		vao					(m_context.getRenderContext());

	// always do the initial clear
	gl.disable(GL_SCISSOR_TEST);
	gl.viewport(0, 0, renderTargetSize.x(), renderTargetSize.y());
	gl.clearColor(yellow.x(), yellow.y(), yellow.z(), yellow.w());
	gl.clear(GL_COLOR_BUFFER_BIT);
	gl.finish();

	// prepare draw
	if (m_scissoredClear)
		gl.enable(GL_SCISSOR_TEST);

	if (m_drawTriangles)
	{
		const deUint32	programHandle		= (m_useGlobalState || !useBBox) ? (m_basicProgram->getProgram()) : (m_perPrimitiveProgram->getProgram());
		const int		positionAttribLoc	= gl.getAttribLocation(programHandle, "a_position");

		TCU_CHECK(positionAttribLoc != -1);

		gl.useProgram(programHandle);
		gl.bindVertexArray(*vao);
		gl.enableVertexAttribArray(positionAttribLoc);
		gl.vertexAttribPointer(positionAttribLoc, 4, GL_FLOAT, GL_FALSE, (int)sizeof(tcu::Vec4), DE_NULL);
		gl.patchParameteri(GL_PATCH_VERTICES, 3);
	}

	// do random scissor/clearldraw operations
	for (int opNdx = 0; opNdx < numOps; ++opNdx)
	{
		const int	drawObjNdx				= (m_drawTriangles) ? (rnd.getInt(0, (int)m_drawObjects.size() - 1)) : (0);
		const int	objectVertexStartNdx	= (m_drawTriangles) ? (m_drawObjects[drawObjNdx].firstNdx) : (0);
		const int	objectVertexLength		= (m_drawTriangles) ? (m_drawObjects[drawObjNdx].numVertices) : (0);
		tcu::Vec4	bboxMin;
		tcu::Vec4	bboxMax;

		if (m_drawTriangles)
		{
			bboxMin = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
			bboxMax = tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f);

			// calc bbox
			for (int vertexNdx = objectVertexStartNdx; vertexNdx < objectVertexStartNdx + objectVertexLength; ++vertexNdx)
			for (int componentNdx = 0; componentNdx < 4; ++componentNdx)
			{
				bboxMin[componentNdx] = de::min(bboxMin[componentNdx], m_objectVertices[vertexNdx][componentNdx]);
				bboxMax[componentNdx] = de::max(bboxMax[componentNdx], m_objectVertices[vertexNdx][componentNdx]);
			}
		}
		else
		{
			// no geometry, just random something
			bboxMin.x() = rnd.getFloat(-1.2f, 1.0f);
			bboxMin.y() = rnd.getFloat(-1.2f, 1.0f);
			bboxMin.z() = rnd.getFloat(-1.2f, 1.0f);
			bboxMin.w() = 1.0f;
			bboxMax.x() = bboxMin.x() + rnd.getFloat(0.2f, 1.0f);
			bboxMax.y() = bboxMin.y() + rnd.getFloat(0.2f, 1.0f);
			bboxMax.z() = bboxMin.z() + rnd.getFloat(0.2f, 1.0f);
			bboxMax.w() = 1.0f;
		}

		if (m_scissoredClear)
		{
			const int scissorX = (m_fullscreenScissor) ? (0)					: rnd.getInt(0, renderTargetSize.x()-1);
			const int scissorY = (m_fullscreenScissor) ? (0)					: rnd.getInt(0, renderTargetSize.y()-1);
			const int scissorW = (m_fullscreenScissor) ? (renderTargetSize.x())	: rnd.getInt(0, renderTargetSize.x()-scissorX);
			const int scissorH = (m_fullscreenScissor) ? (renderTargetSize.y())	: rnd.getInt(0, renderTargetSize.y()-scissorY);

			gl.scissor(scissorX, scissorY, scissorW, scissorH);
		}

		{
			const tcu::Vec4 color = tcu::mix(green, yellow, rnd.getFloat() * 0.4f); // greenish
			gl.clearColor(color.x(), color.y(), color.z(), color.w());
			gl.clear(GL_COLOR_BUFFER_BIT);
		}

		if (useBBox)
		{
			DE_ASSERT(m_useGlobalState || m_drawTriangles); // !m_useGlobalState -> m_drawTriangles

			auto boundingBoxFunc = getBoundingBoxFunction(m_context);
			if (m_useGlobalState)
				boundingBoxFunc(bboxMin.x(), bboxMin.y(), bboxMin.z(), bboxMin.w(),
						bboxMax.x(), bboxMax.y(), bboxMax.z(), bboxMax.w());
		}

		if (m_drawTriangles)
			gl.drawArrays(GL_PATCHES, objectVertexStartNdx, objectVertexLength);
	}

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

bool ClearCase::verifyImagesEqual (const tcu::PixelBufferAccess& withoutBBox, const tcu::PixelBufferAccess& withBBox)
{
	DE_ASSERT(withoutBBox.getWidth() == withBBox.getWidth());
	DE_ASSERT(withoutBBox.getHeight() == withBBox.getHeight());

	tcu::Surface	errorMask	(withoutBBox.getWidth(), withoutBBox.getHeight());
	bool			anyError	= false;

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

	for (int y = 0; y < withoutBBox.getHeight(); ++y)
	for (int x = 0; x < withoutBBox.getWidth(); ++x)
	{
		if (withoutBBox.getPixelInt(x, y) != withBBox.getPixelInt(x, y))
		{
			errorMask.setPixel(x, y, tcu::RGBA::red());
			anyError = true;
		}
	}

	if (anyError)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image comparison failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image comparison")
			<< tcu::TestLog::Image("WithoutBBox", "Result with bounding box not set", withoutBBox)
			<< tcu::TestLog::Image("WithBBox", "Result with bounding box set", withBBox)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
			<< tcu::TestLog::EndImageSet;
	}

	return !anyError;
}

bool ClearCase::verifyImageResultValid (const tcu::PixelBufferAccess& result)
{
	tcu::Surface	errorMask	(result.getWidth(), result.getHeight());
	bool			anyError	= false;

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

	for (int y = 0; y < result.getHeight(); ++y)
	for (int x = 0; x < result.getWidth(); ++x)
	{
		const tcu::IVec4 pixel = result.getPixelInt(x, y);

		// allow green, yellow and any shade between
		if (pixel[1] != 255 || pixel[2] != 0)
		{
			errorMask.setPixel(x, y, tcu::RGBA::red());
			anyError = true;
		}
	}

	if (anyError)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("ResultImage", "Result image", result)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
			<< tcu::TestLog::EndImageSet;
	}

	return !anyError;
}

static const char* const s_yellowishPosOnlyVertexSource =	"${GLSL_VERSION_DECL}\n"
															"in highp vec4 a_position;\n"
															"out highp vec4 v_vertex_color;\n"
															"void main()\n"
															"{\n"
															"	gl_Position = a_position;\n"
															"	// yellowish shade\n"
															"	highp float redComponent = 0.5 + float(gl_VertexID % 5) / 8.0;\n"
															"	v_vertex_color = vec4(redComponent, 1.0, 0.0, 1.0);\n"
															"}\n";

static const char* const s_basicColorFragmentSource =	"${GLSL_VERSION_DECL}\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";


static const char* const s_basicColorTessEvalSource =	"${GLSL_VERSION_DECL}\n"
														"${TESSELLATION_SHADER_REQUIRE}\n"
														"${GPU_SHADER5_REQUIRE}\n"
														"layout(triangles) in;\n"
														"in highp vec4 v_tess_eval_color[];\n"
														"out highp vec4 v_color;\n"
														"precise gl_Position;\n"
														"void main()\n"
														"{\n"
														"	gl_Position = gl_TessCoord.x * gl_in[0].gl_Position\n"
														"	            + gl_TessCoord.y * gl_in[1].gl_Position\n"
														"	            + gl_TessCoord.z * gl_in[2].gl_Position;\n"
														"	v_color = gl_TessCoord.x * v_tess_eval_color[0]\n"
														"	        + gl_TessCoord.y * v_tess_eval_color[1]\n"
														"	        + gl_TessCoord.z * v_tess_eval_color[2];\n"
														"}\n";

std::string ClearCase::genVertexSource (void) const
{
	return	s_yellowishPosOnlyVertexSource;
}

std::string ClearCase::genFragmentSource (void) const
{
	return s_basicColorFragmentSource;
}

std::string ClearCase::genTessellationControlSource (bool setBBox) const
{
	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n";

	if (setBBox)
		buf << "${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n";

	buf <<	"layout(vertices=3) out;\n"
			"in highp vec4 v_vertex_color[];\n"
			"out highp vec4 v_tess_eval_color[];\n"
			"void main()\n"
			"{\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
			"	v_tess_eval_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
			"	gl_TessLevelOuter[0] = 2.8;\n"
			"	gl_TessLevelOuter[1] = 2.8;\n"
			"	gl_TessLevelOuter[2] = 2.8;\n"
			"	gl_TessLevelInner[0] = 2.8;\n";

	if (setBBox)
	{
		buf <<	"\n"
		"	${PRIM_GL_BOUNDING_BOX}[0] = min(min(gl_in[0].gl_Position,\n"
		"	                               gl_in[1].gl_Position),\n"
		"	                           gl_in[2].gl_Position);\n"
		"	${PRIM_GL_BOUNDING_BOX}[1] = max(max(gl_in[0].gl_Position,\n"
		"	                               gl_in[1].gl_Position),\n"
		"	                           gl_in[2].gl_Position);\n";
	}

	buf << "}\n";
	return buf.str();
}

std::string ClearCase::genTessellationEvaluationSource (void) const
{
	return s_basicColorTessEvalSource;
}

class ViewportCallOrderCase : public TestCase
{
public:
	enum CallOrder
	{
		VIEWPORT_FIRST = 0,
		BBOX_FIRST,

		ORDER_LAST
	};

									ViewportCallOrderCase			(Context& context, const char* name, const char* description, CallOrder callOrder);
									~ViewportCallOrderCase			(void);

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

	void							genVbo							(void);
	void							genProgram						(void);
	bool							verifyImage						(const tcu::PixelBufferAccess& result);

	std::string						genVertexSource					(void) const;
	std::string						genFragmentSource				(void) const;
	std::string						genTessellationControlSource	(void) const;
	std::string						genTessellationEvaluationSource	(void) const;

	const CallOrder					m_callOrder;

	de::MovePtr<glu::Buffer>		m_vbo;
	glw::GLuint				m_vao;
	de::MovePtr<glu::ShaderProgram>	m_program;
	int								m_numVertices;
};

ViewportCallOrderCase::ViewportCallOrderCase (Context& context, const char* name, const char* description, CallOrder callOrder)
	: TestCase		(context, name, description)
	, m_callOrder	(callOrder)
	, m_vao		(0)
	, m_numVertices	(-1)
{
	DE_ASSERT(m_callOrder < ORDER_LAST);
}

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

void ViewportCallOrderCase::init (void)
{
	const bool hasES32OrGL45 = supportsES32OrGL45(m_context);

	if (!boundingBoxSupported(m_context))
		throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");

	if (!hasES32OrGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing call order of state setting functions have no effect on the rendering.\n"
		<< "Setting viewport and bounding box in the following order:\n"
			<< ((m_callOrder == VIEWPORT_FIRST)
				? ("\tFirst viewport with glViewport function.\n")
				: ("\tFirst bounding box with glPrimitiveBoundingBoxEXT function.\n"))
			<< ((m_callOrder == VIEWPORT_FIRST)
				? ("\tThen bounding box with glPrimitiveBoundingBoxEXT function.\n")
				: ("\tThen viewport with glViewport function.\n"))
		<< "Verifying rendering result."
		<< tcu::TestLog::EndMessage;

	// resources
	genVbo();
	genProgram();
}

void ViewportCallOrderCase::deinit (void)
{
	m_vbo.clear();
	m_program.clear();

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

ViewportCallOrderCase::IterateResult ViewportCallOrderCase::iterate (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	const tcu::IVec2		viewportSize	= tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
	const glw::GLint		posLocation		= gl.getAttribLocation(m_program->getProgram(), "a_position");
	tcu::Surface			resultSurface	(viewportSize.x(), viewportSize.y());

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

	// set state
	for (int orderNdx = 0; orderNdx < 2; ++orderNdx)
	{
		if ((orderNdx == 0 && m_callOrder == VIEWPORT_FIRST) ||
			(orderNdx == 1 && m_callOrder == BBOX_FIRST))
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "Setting viewport to cover the left half of the render target.\n"
				<< "\t(0, 0, " << (viewportSize.x()/2) << ", " << viewportSize.y() << ")"
				<< tcu::TestLog::EndMessage;

			gl.viewport(0, 0, viewportSize.x()/2, viewportSize.y());
		}
		else
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "Setting bounding box to cover the right half of the clip space.\n"
				<< "\t(0.0, -1.0, -1.0, 1.0) .. (1.0, 1.0, 1.0f, 1.0)"
				<< tcu::TestLog::EndMessage;

			auto boundingBoxFunc = getBoundingBoxFunction(m_context);

			boundingBoxFunc(0.0f, -1.0f, -1.0f, 1.0f, 1.0f,  1.0f,  1.0f, 1.0f);
		}
	}

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Rendering mesh covering the right half of the clip space."
		<< tcu::TestLog::EndMessage;

	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, sizeof(float[4]), (const float*)DE_NULL);
	gl.enableVertexAttribArray(posLocation);
	gl.useProgram(m_program->getProgram());
	gl.patchParameteri(GL_PATCH_VERTICES, 3);
	gl.drawArrays(GL_PATCHES, 0, m_numVertices);
	GLU_EXPECT_NO_ERROR(gl.getError(), "post-draw");

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying image"
		<< tcu::TestLog::EndMessage;
	glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());

	if (!verifyImage(resultSurface.getAccess()))
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Result ok."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("Result", "Result", resultSurface.getAccess())
			<< tcu::TestLog::EndImageSet;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	return STOP;
}

void ViewportCallOrderCase::genVbo (void)
{
	const int				gridSize	= 6;
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	std::vector<tcu::Vec4>	data		(gridSize * gridSize * 2 * 3);
	std::vector<int>		cellOrder	(gridSize * gridSize * 2);
	de::Random				rnd			(0x55443322);

	// generate grid with triangles in random order
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
		cellOrder[ndx] = ndx;
	rnd.shuffle(cellOrder.begin(), cellOrder.end());

	// generate grid filling the right half of the clip space: (x: 0.0, y: -1.0) .. (x: 1.0, y: 1.0)
	for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
	{
		const int			cellNdx		= cellOrder[ndx];
		const bool			cellSide	= ((cellNdx % 2) == 0);
		const int			cellX		= (cellNdx / 2) % gridSize;
		const int			cellY		= (cellNdx / 2) / gridSize;

		if (cellSide)
		{
			data[ndx * 3 + 0] = tcu::Vec4(float(cellX+0) / float(gridSize), (float(cellY+0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
			data[ndx * 3 + 1] = tcu::Vec4(float(cellX+1) / float(gridSize), (float(cellY+1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
			data[ndx * 3 + 2] = tcu::Vec4(float(cellX+0) / float(gridSize), (float(cellY+1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
		}
		else
		{
			data[ndx * 3 + 0] = tcu::Vec4(float(cellX+0) / float(gridSize), (float(cellY+0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
			data[ndx * 3 + 1] = tcu::Vec4(float(cellX+1) / float(gridSize), (float(cellY+0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
			data[ndx * 3 + 2] = tcu::Vec4(float(cellX+1) / float(gridSize), (float(cellY+1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
		}
	}

	// Generate VAO for desktop OpenGL
	if (!glu::isContextTypeES(m_context.getRenderContext().getType())) {
		gl.genVertexArrays(1, &m_vao);
		gl.bindVertexArray(m_vao);
	}

	m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
	gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
	gl.bufferData(GL_ARRAY_BUFFER, (int)(data.size() * sizeof(tcu::Vec4)), &data[0], GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "create vbo");

	m_numVertices = (int)data.size();
}

void ViewportCallOrderCase::genProgram (void)
{
	m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(),
																	   glu::ProgramSources()
																			<< glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()))
																			<< glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()))
																			<< glu::TessellationControlSource(specializeShader(m_context, genTessellationControlSource().c_str()))
																			<< glu::TessellationEvaluationSource(specializeShader(m_context, genTessellationEvaluationSource().c_str()))));

	m_testCtx.getLog()
		<< tcu::TestLog::Section("Program", "Shader program")
		<< *m_program
		<< tcu::TestLog::EndSection;

	if (!m_program->isOk())
		throw tcu::TestError("shader build failed");
}

bool ViewportCallOrderCase::verifyImage (const tcu::PixelBufferAccess& result)
{
	const tcu::IVec2	insideBorder	(deCeilFloatToInt32(0.25f * (float)result.getWidth()) + 1, deFloorFloatToInt32(0.5f * (float)result.getWidth()) - 1);
	const tcu::IVec2	outsideBorder	(deFloorFloatToInt32(0.25f * (float)result.getWidth()) - 1, deCeilFloatToInt32(0.5f * (float)result.getWidth()) + 1);
	tcu::Surface		errorMask		(result.getWidth(), result.getHeight());
	bool				anyError		= false;

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

	for (int y = 0; y < result.getHeight(); ++y)
	for (int x = 0; x < result.getWidth(); ++x)
	{
		/*
			Test stores the xmin,xmax values in the insideBorder and outsideBorder vectors.
			Thus the "y" in the vector is xmax.
		*/

		const tcu::IVec4	pixel			= result.getPixelInt(x, y);
		const bool			insideMeshArea	= x >= insideBorder.x() && x <= insideBorder.y();
		const bool			outsideMeshArea	= x <= outsideBorder.x() && x >= outsideBorder.y();

		// inside mesh, allow green, yellow and any shade between
		// outside mesh, allow background (black) only
		// in the border area, allow anything
		if ((insideMeshArea && (pixel[1] != 255 || pixel[2] != 0)) ||
			(outsideMeshArea && (pixel[0] != 0 || pixel[1] != 0 || pixel[2] != 0)))
		{
			errorMask.setPixel(x, y, tcu::RGBA::red());
			anyError = true;
		}
	}

	if (anyError)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Images", "Image verification")
			<< tcu::TestLog::Image("ResultImage", "Result image", result)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
			<< tcu::TestLog::EndImageSet;
	}

	return !anyError;
}

std::string ViewportCallOrderCase::genVertexSource (void) const
{
	return	s_yellowishPosOnlyVertexSource;
}

std::string ViewportCallOrderCase::genFragmentSource (void) const
{
	return s_basicColorFragmentSource;
}

std::string ViewportCallOrderCase::genTessellationControlSource (void) const
{
	return	"${GLSL_VERSION_DECL}\n"
			"${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
			"${TESSELLATION_SHADER_REQUIRE}\n"
			"layout(vertices=3) out;\n"
			"in highp vec4 v_vertex_color[];\n"
			"out highp vec4 v_tess_eval_color[];\n"
			"void main()\n"
			"{\n"
			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
			"	v_tess_eval_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
			"	gl_TessLevelOuter[0] = 2.8;\n"
			"	gl_TessLevelOuter[1] = 2.8;\n"
			"	gl_TessLevelOuter[2] = 2.8;\n"
			"	gl_TessLevelInner[0] = 2.8;\n"
			"}\n";
}

std::string ViewportCallOrderCase::genTessellationEvaluationSource (void) const
{
	return s_basicColorTessEvalSource;
}

} // anonymous

PrimitiveBoundingBoxTests::PrimitiveBoundingBoxTests (Context& context)
	: TestCaseGroup(context, "primitive_bounding_box", "Tests for EXT_primitive_bounding_box")
{
}

PrimitiveBoundingBoxTests::~PrimitiveBoundingBoxTests (void)
{
}

void PrimitiveBoundingBoxTests::init (void)
{
	static const struct
	{
		const char*	name;
		const char*	description;
		deUint32	methodFlags;
	} stateSetMethods[] =
	{
		{
			"global_state",
			"Set bounding box using PRIMITIVE_BOUNDING_BOX_EXT state",
			BBoxRenderCase::FLAG_SET_BBOX_STATE,
		},
		{
			"tessellation_set_per_draw",
			"Set bounding box using gl_BoundingBoxEXT, use same value for all primitives",
			BBoxRenderCase::FLAG_SET_BBOX_OUTPUT,
		},
		{
			"tessellation_set_per_primitive",
			"Set bounding box using gl_BoundingBoxEXT, use per-primitive bounding box",
			BBoxRenderCase::FLAG_SET_BBOX_OUTPUT | BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
		},
	};
	static const struct
	{
		const char*	name;
		const char*	description;
		deUint32	stageFlags;
	} pipelineConfigs[] =
	{
		{
			"vertex_fragment",
			"Render with vertex-fragment program",
			0u
		},
		{
			"vertex_tessellation_fragment",
			"Render with vertex-tessellation{ctrl,eval}-fragment program",
			BBoxRenderCase::FLAG_TESSELLATION
		},
		{
			"vertex_geometry_fragment",
			"Render with vertex-tessellation{ctrl,eval}-geometry-fragment program",
			BBoxRenderCase::FLAG_GEOMETRY
		},
		{
			"vertex_tessellation_geometry_fragment",
			"Render with vertex-geometry-fragment program",
			BBoxRenderCase::FLAG_TESSELLATION | BBoxRenderCase::FLAG_GEOMETRY
		},
	};
	static const struct
	{
		const char*	name;
		const char*	description;
		deUint32	flags;
		deUint32	invalidFlags;
		deUint32	requiredFlags;
	} usageConfigs[] =
	{
		{
			"default_framebuffer_bbox_equal",
			"Render to default framebuffer, set tight bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
			0
		},
		{
			"default_framebuffer_bbox_larger",
			"Render to default framebuffer, set padded bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_LARGER,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
			0
		},
		{
			"default_framebuffer_bbox_smaller",
			"Render to default framebuffer, set too small bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_SMALLER,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
			0
		},
		{
			"fbo_bbox_equal",
			"Render to texture, set tight bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
			0
		},
		{
			"fbo_bbox_larger",
			"Render to texture, set padded bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_LARGER,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
			0
		},
		{
			"fbo_bbox_smaller",
			"Render to texture, set too small bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_SMALLER,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
			0
		},
		{
			"default_framebuffer",
			"Render to default framebuffer, set tight bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
			0,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX
		},
		{
			"fbo",
			"Render to texture, set tight bounding box",
			BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
			0,
			BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX
		},
	};
	enum PrimitiveRenderType
	{
		TYPE_TRIANGLE,
		TYPE_LINE,
		TYPE_POINT,
	};
	const struct
	{
		const char*			name;
		const char*			description;
		PrimitiveRenderType	type;
		deUint32			flags;
	} primitiveTypes[] =
	{
		{
			"triangles",
			"Triangle render tests",
			TYPE_TRIANGLE,
			0
		},
		{
			"lines",
			"Line render tests",
			TYPE_LINE,
			0
		},
		{
			"points",
			"Point render tests",
			TYPE_POINT,
			0
		},
		{
			"wide_lines",
			"Wide line render tests",
			TYPE_LINE,
			LineRenderCase::LINEFLAG_WIDE
		},
		{
			"wide_points",
			"Wide point render tests",
			TYPE_POINT,
			PointRenderCase::POINTFLAG_WIDE
		},
	};

	// .state_query
	{
		tcu::TestCaseGroup* const stateQueryGroup = new tcu::TestCaseGroup(m_testCtx, "state_query", "State queries");
		addChild(stateQueryGroup);

		stateQueryGroup->addChild(new InitialValueCase	(m_context,	"initial_value",	"Initial value case"));
		stateQueryGroup->addChild(new QueryCase			(m_context,	"getfloat",			"getFloatv",			QueryCase::QUERY_FLOAT));
		stateQueryGroup->addChild(new QueryCase			(m_context,	"getboolean",		"getBooleanv",			QueryCase::QUERY_BOOLEAN));
		stateQueryGroup->addChild(new QueryCase			(m_context,	"getinteger",		"getIntegerv",			QueryCase::QUERY_INT));
		stateQueryGroup->addChild(new QueryCase			(m_context,	"getinteger64",		"getInteger64v",		QueryCase::QUERY_INT64));
	}

	// .triangles
	// .(wide_)lines
	// .(wide_)points
	for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
	{
		tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(m_testCtx, primitiveTypes[primitiveTypeNdx].name, primitiveTypes[primitiveTypeNdx].description);
		addChild(primitiveGroup);

		for (int stateSetMethodNdx = 0; stateSetMethodNdx < DE_LENGTH_OF_ARRAY(stateSetMethods); ++stateSetMethodNdx)
		{
			tcu::TestCaseGroup* const methodGroup = new tcu::TestCaseGroup(m_testCtx, stateSetMethods[stateSetMethodNdx].name, stateSetMethods[stateSetMethodNdx].description);
			primitiveGroup->addChild(methodGroup);

			for (int pipelineConfigNdx = 0; pipelineConfigNdx < DE_LENGTH_OF_ARRAY(pipelineConfigs); ++pipelineConfigNdx)
			{
				if ((stateSetMethods[stateSetMethodNdx].methodFlags & BBoxRenderCase::FLAG_SET_BBOX_OUTPUT) != 0 &&
					(pipelineConfigs[pipelineConfigNdx].stageFlags  & BBoxRenderCase::FLAG_TESSELLATION)    == 0)
				{
					// invalid config combination
				}
				else
				{
					tcu::TestCaseGroup* const pipelineGroup = new tcu::TestCaseGroup(m_testCtx, pipelineConfigs[pipelineConfigNdx].name, pipelineConfigs[pipelineConfigNdx].description);
					methodGroup->addChild(pipelineGroup);

					for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageConfigs); ++usageNdx)
					{
						const deUint32 flags = primitiveTypes[primitiveTypeNdx].flags         |
											   stateSetMethods[stateSetMethodNdx].methodFlags |
											   pipelineConfigs[pipelineConfigNdx].stageFlags  |
											   usageConfigs[usageNdx].flags;

						if (usageConfigs[usageNdx].invalidFlags && (flags & usageConfigs[usageNdx].invalidFlags) != 0)
							continue;
						if (usageConfigs[usageNdx].requiredFlags && (flags & usageConfigs[usageNdx].requiredFlags) == 0)
							continue;

						switch (primitiveTypes[primitiveTypeNdx].type)
						{
							case TYPE_TRIANGLE:
								pipelineGroup->addChild(new GridRenderCase(m_context, usageConfigs[usageNdx].name, usageConfigs[usageNdx].description, flags));
								break;
							case TYPE_LINE:
								pipelineGroup->addChild(new LineRenderCase(m_context, usageConfigs[usageNdx].name, usageConfigs[usageNdx].description, flags));
								break;
							case TYPE_POINT:
								pipelineGroup->addChild(new PointRenderCase(m_context, usageConfigs[usageNdx].name, usageConfigs[usageNdx].description, flags));
								break;
							default:
								DE_ASSERT(false);
						}
					}
				}
			}
		}
	}

	// .depth
	{
		static const struct
		{
			const char*					name;
			const char*					description;
			DepthDrawCase::DepthType	depthMethod;
		} depthMethods[] =
		{
			{
				"builtin_depth",
				"Fragment depth not modified in fragment shader",
				DepthDrawCase::DEPTH_BUILTIN
			},
			{
				"user_defined_depth",
				"Fragment depth is defined in the fragment shader",
				DepthDrawCase::DEPTH_USER_DEFINED
			},
		};
		static const struct
		{
			const char*					name;
			const char*					description;
			DepthDrawCase::BBoxState	bboxState;
			DepthDrawCase::BBoxSize		bboxSize;
		} depthCases[] =
		{
			{
				"global_state_bbox_equal",
				"Test tight bounding box with global bbox state",
				DepthDrawCase::STATE_GLOBAL,
				DepthDrawCase::BBOX_EQUAL,
			},
			{
				"global_state_bbox_larger",
				"Test padded bounding box with global bbox state",
				DepthDrawCase::STATE_GLOBAL,
				DepthDrawCase::BBOX_LARGER,
			},
			{
				"per_primitive_bbox_equal",
				"Test tight bounding box with tessellation output bbox",
				DepthDrawCase::STATE_PER_PRIMITIVE,
				DepthDrawCase::BBOX_EQUAL,
			},
			{
				"per_primitive_bbox_larger",
				"Test padded bounding box with tessellation output bbox",
				DepthDrawCase::STATE_PER_PRIMITIVE,
				DepthDrawCase::BBOX_LARGER,
			},
		};

		tcu::TestCaseGroup* const depthGroup = new tcu::TestCaseGroup(m_testCtx, "depth", "Test bounding box depth component");
		addChild(depthGroup);

		// .builtin_depth
		// .user_defined_depth
		for (int depthNdx = 0; depthNdx < DE_LENGTH_OF_ARRAY(depthMethods); ++depthNdx)
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, depthMethods[depthNdx].name, depthMethods[depthNdx].description);
			depthGroup->addChild(group);

			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(depthCases); ++caseNdx)
				group->addChild(new DepthDrawCase(m_context, depthCases[caseNdx].name, depthCases[caseNdx].description, depthMethods[depthNdx].depthMethod, depthCases[caseNdx].bboxState, depthCases[caseNdx].bboxSize));
		}
	}

	// .blit_fbo
	{
		tcu::TestCaseGroup* const blitFboGroup = new tcu::TestCaseGroup(m_testCtx, "blit_fbo", "Test bounding box does not affect blitting");
		addChild(blitFboGroup);

		blitFboGroup->addChild(new BlitFboCase(m_context, "blit_default_to_fbo", "Blit from default fb to fbo", BlitFboCase::TARGET_DEFAULT, BlitFboCase::TARGET_FBO));
		blitFboGroup->addChild(new BlitFboCase(m_context, "blit_fbo_to_default", "Blit from fbo to default fb", BlitFboCase::TARGET_FBO,     BlitFboCase::TARGET_DEFAULT));
		blitFboGroup->addChild(new BlitFboCase(m_context, "blit_fbo_to_fbo",     "Blit from fbo to fbo",        BlitFboCase::TARGET_FBO,     BlitFboCase::TARGET_FBO));
	}

	// .clear
	{
		tcu::TestCaseGroup* const clearGroup = new tcu::TestCaseGroup(m_testCtx, "clear", "Test bounding box does not clears");
		addChild(clearGroup);

		clearGroup->addChild(new ClearCase(m_context, "full_clear",                                             "Do full clears",                                               0));
		clearGroup->addChild(new ClearCase(m_context, "full_clear_with_triangles",                              "Do full clears and render some geometry",                      ClearCase::DRAW_TRIANGLE_BIT));
		clearGroup->addChild(new ClearCase(m_context, "full_clear_with_triangles_per_primitive_bbox",           "Do full clears and render some geometry",                      ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
		clearGroup->addChild(new ClearCase(m_context, "scissored_clear",                                        "Do scissored clears",                                          ClearCase::SCISSOR_CLEAR_BIT));
		clearGroup->addChild(new ClearCase(m_context, "scissored_clear_with_triangles",                         "Do scissored clears and render some geometry",                 ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT));
		clearGroup->addChild(new ClearCase(m_context, "scissored_clear_with_triangles_per_primitive_bbox",      "Do scissored clears and render some geometry",                 ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
		clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear",                                   "Do full clears with enabled scissor",                          ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT));
		clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear_with_triangles",                    "Do full clears with enabled scissor and render some geometry", ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT));
		clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear_with_triangles_per_primitive_bbox", "Do full clears with enabled scissor and render some geometry", ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
	}

	// .call_order (Khronos bug #13262)
	{
		tcu::TestCaseGroup* const callOrderGroup = new tcu::TestCaseGroup(m_testCtx, "call_order", "Test viewport and bounding box calls have no effect");
		addChild(callOrderGroup);

		callOrderGroup->addChild(new ViewportCallOrderCase(m_context, "viewport_first_bbox_second", "Set up viewport first and bbox after", ViewportCallOrderCase::VIEWPORT_FIRST));
		callOrderGroup->addChild(new ViewportCallOrderCase(m_context, "bbox_first_viewport_second", "Set up bbox first and viewport after", ViewportCallOrderCase::BBOX_FIRST));
	}
}

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