/*-------------------------------------------------------------------------
 * 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 unusedZ = a_position.z;\n"
				"	highp float writtenZ = a_position.w;\n"
				"	gl_Position = vec4(a_position.xy, unusedZ, 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 unusedZ = tessellatedPos.z;\n"
				"	highp float writtenZ = tessellatedPos.w;\n"
				"	gl_Position = vec4(tessellatedPos.xy, unusedZ, 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
