/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Drawing tests.
 *//*--------------------------------------------------------------------*/

#include "es31fDrawTests.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deMemory.h"
#include "tcuRenderTarget.hpp"
#include "tcuVectorUtil.hpp"
#include "sglrGLContext.hpp"
#include "glsDrawTest.hpp"
#include "gluStrUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluCallLogWrapper.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include <set>

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

enum TestIterationType
{
	TYPE_DRAW_COUNT,		// !< test with 1, 5, and 25 primitives
	TYPE_INSTANCE_COUNT,	// !< test with 1, 4, and 11 instances

	TYPE_LAST
};

static const char* s_commonVertexShaderSource =		"#version 310 es\n"
													"in highp vec4 a_position;\n"
													"void main (void)\n"
													"{\n"
													"	gl_Position = a_position;\n"
													"}\n";
static const char* s_commonFragmentShaderSource	=	"#version 310 es\n"
													"layout(location = 0) out highp vec4 fragColor;\n"
													"void main (void)\n"
													"{\n"
													"	fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
													"}\n";

static const char* s_colorVertexShaderSource =		"#version 310 es\n"
													"in highp vec4 a_position;\n"
													"in highp vec4 a_color;\n"
													"out highp vec4 v_color;\n"
													"void main (void)\n"
													"{\n"
													"	gl_Position = a_position;\n"
													"	v_color = a_color;\n"
													"}\n";
static const char* s_colorFragmentShaderSource	=	"#version 310 es\n"
													"layout(location = 0) out highp vec4 fragColor;\n"
													"in highp vec4 v_color;\n"
													"void main (void)\n"
													"{\n"
													"	fragColor = v_color;\n"
													"}\n";
struct DrawElementsCommand
{
	deUint32 count;
	deUint32 primCount;
	deUint32 firstIndex;
	deInt32  baseVertex;
	deUint32 reservedMustBeZero;
};
DE_STATIC_ASSERT(5 * sizeof(deUint32) == sizeof(DrawElementsCommand)); // tight packing

struct DrawArraysCommand
{
	deUint32 count;
	deUint32 primCount;
	deUint32 first;
	deUint32 reservedMustBeZero;
};
DE_STATIC_ASSERT(4 * sizeof(deUint32) == sizeof(DrawArraysCommand)); // tight packing

// Verifies image contains only yellow or greeen, or a linear combination
// of these colors.
static bool verifyImageYellowGreen (const tcu::Surface& image, tcu::TestLog& log)
{
	using tcu::TestLog;

	const int colorThreshold	= 20;

	tcu::Surface error			(image.getWidth(), image.getHeight());
	bool isOk					= true;

	for (int y = 0; y < image.getHeight(); y++)
	for (int x = 0; x < image.getWidth(); x++)
	{
		const tcu::RGBA pixel = image.getPixel(x, y);
		bool pixelOk = true;

		// Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
		if (de::abs(pixel.getGreen() - 255) > colorThreshold)
			pixelOk = false;

		// Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
		if (de::abs(pixel.getBlue() - 0) > colorThreshold)
			pixelOk = false;

		error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
		isOk = isOk && pixelOk;
	}

	if (!isOk)
	{
		log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
		log << TestLog::ImageSet("Verfication result", "Result of rendering")
			<< TestLog::Image("Result",		"Result",		image)
			<< TestLog::Image("ErrorMask",	"Error mask",	error)
			<< TestLog::EndImageSet;
	}
	else
	{
		log << TestLog::ImageSet("Verfication result", "Result of rendering")
			<< TestLog::Image("Result", "Result", image)
			<< TestLog::EndImageSet;
	}

	return isOk;
}

static void addTestIterations (gls::DrawTest* test, gls::DrawTestSpec& spec, TestIterationType type)
{
	if (type == TYPE_DRAW_COUNT)
	{
		spec.primitiveCount = 1;
		test->addIteration(spec, "draw count = 1");

		spec.primitiveCount = 5;
		test->addIteration(spec, "draw count = 5");

		spec.primitiveCount = 25;
		test->addIteration(spec, "draw count = 25");
	}
	else if (type == TYPE_INSTANCE_COUNT)
	{
		spec.instanceCount = 1;
		test->addIteration(spec, "instance count = 1");

		spec.instanceCount = 4;
		test->addIteration(spec, "instance count = 4");

		spec.instanceCount = 11;
		test->addIteration(spec, "instance count = 11");
	}
	else
		DE_ASSERT(false);
}

static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
{
	spec.apiType							= glu::ApiType::es(3,1);
	spec.primitive							= gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
	spec.primitiveCount						= 5;
	spec.drawMethod							= method;
	spec.indexType							= gls::DrawTestSpec::INDEXTYPE_LAST;
	spec.indexPointerOffset					= 0;
	spec.indexStorage						= gls::DrawTestSpec::STORAGE_LAST;
	spec.first								= 0;
	spec.indexMin							= 0;
	spec.indexMax							= 0;
	spec.instanceCount						= 1;
	spec.indirectOffset						= 0;

	spec.attribs.resize(2);

	spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
	spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
	spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
	spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
	spec.attribs[0].componentCount			= 4;
	spec.attribs[0].offset					= 0;
	spec.attribs[0].stride					= 0;
	spec.attribs[0].normalize				= false;
	spec.attribs[0].instanceDivisor			= 0;
	spec.attribs[0].useDefaultAttribute		= false;

	spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
	spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
	spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
	spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
	spec.attribs[1].componentCount			= 2;
	spec.attribs[1].offset					= 0;
	spec.attribs[1].stride					= 0;
	spec.attribs[1].normalize				= false;
	spec.attribs[1].instanceDivisor			= 0;
	spec.attribs[1].useDefaultAttribute		= false;
}

static std::string sizeToString (int size)
{
	if (size < 1024)
		return de::toString(size) + " byte(s)";
	if (size < 1024*1024)
		return de::toString(size / 1024) + " KB";
	return de::toString(size / 1024 / 1024) + " MB";
}

class AttributeGroup : public TestCaseGroup
{
public:
									AttributeGroup	(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage);
									~AttributeGroup	(void);

	void							init			(void);

private:
	gls::DrawTestSpec::DrawMethod	m_method;
	gls::DrawTestSpec::Primitive	m_primitive;
	gls::DrawTestSpec::IndexType	m_indexType;
	gls::DrawTestSpec::Storage		m_indexStorage;
};

AttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
	: TestCaseGroup		(context, name, descr)
	, m_method			(drawMethod)
	, m_primitive		(primitive)
	, m_indexType		(indexType)
	, m_indexStorage	(indexStorage)
{
}

AttributeGroup::~AttributeGroup (void)
{
}

void AttributeGroup::init (void)
{
	// Single attribute
	{
		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
		gls::DrawTestSpec	spec;

		spec.apiType							= glu::ApiType::es(3,1);
		spec.primitive							= m_primitive;
		spec.primitiveCount						= 5;
		spec.drawMethod							= m_method;
		spec.indexType							= m_indexType;
		spec.indexPointerOffset					= 0;
		spec.indexStorage						= m_indexStorage;
		spec.first								= 0;
		spec.indexMin							= 0;
		spec.indexMax							= 0;
		spec.instanceCount						= 1;
		spec.indirectOffset						= 0;

		spec.attribs.resize(1);

		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
		spec.attribs[0].componentCount			= 2;
		spec.attribs[0].offset					= 0;
		spec.attribs[0].stride					= 0;
		spec.attribs[0].normalize				= false;
		spec.attribs[0].instanceDivisor			= 0;
		spec.attribs[0].useDefaultAttribute		= false;

		addTestIterations(test, spec, TYPE_DRAW_COUNT);

		this->addChild(test);
	}

	// Multiple attribute
	{
		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
		gls::DrawTestSpec	spec;

		spec.apiType							= glu::ApiType::es(3,1);
		spec.primitive							= m_primitive;
		spec.primitiveCount						= 5;
		spec.drawMethod							= m_method;
		spec.indexType							= m_indexType;
		spec.indexPointerOffset					= 0;
		spec.indexStorage						= m_indexStorage;
		spec.first								= 0;
		spec.indexMin							= 0;
		spec.indexMax							= 0;
		spec.instanceCount						= 1;
		spec.indirectOffset						= 0;

		spec.attribs.resize(2);

		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
		spec.attribs[0].componentCount			= 4;
		spec.attribs[0].offset					= 0;
		spec.attribs[0].stride					= 0;
		spec.attribs[0].normalize				= false;
		spec.attribs[0].instanceDivisor			= 0;
		spec.attribs[0].useDefaultAttribute		= false;

		spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
		spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
		spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
		spec.attribs[1].componentCount			= 2;
		spec.attribs[1].offset					= 0;
		spec.attribs[1].stride					= 0;
		spec.attribs[1].normalize				= false;
		spec.attribs[1].instanceDivisor			= 0;
		spec.attribs[1].useDefaultAttribute		= false;

		addTestIterations(test, spec, TYPE_DRAW_COUNT);

		this->addChild(test);
	}

	// Multiple attribute, second one divided
	{
		gls::DrawTest*		test					= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
		gls::DrawTestSpec	spec;

		spec.apiType								= glu::ApiType::es(3,1);
		spec.primitive								= m_primitive;
		spec.primitiveCount							= 5;
		spec.drawMethod								= m_method;
		spec.indexType								= m_indexType;
		spec.indexPointerOffset						= 0;
		spec.indexStorage							= m_indexStorage;
		spec.first									= 0;
		spec.indexMin								= 0;
		spec.indexMax								= 0;
		spec.instanceCount							= 1;
		spec.indirectOffset							= 0;

		spec.attribs.resize(3);

		spec.attribs[0].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
		spec.attribs[0].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
		spec.attribs[0].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.attribs[0].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
		spec.attribs[0].componentCount				= 4;
		spec.attribs[0].offset						= 0;
		spec.attribs[0].stride						= 0;
		spec.attribs[0].normalize					= false;
		spec.attribs[0].instanceDivisor				= 0;
		spec.attribs[0].useDefaultAttribute			= false;

		// Add another position component so the instances wont be drawn on each other
		spec.attribs[1].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
		spec.attribs[1].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
		spec.attribs[1].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.attribs[1].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
		spec.attribs[1].componentCount				= 2;
		spec.attribs[1].offset						= 0;
		spec.attribs[1].stride						= 0;
		spec.attribs[1].normalize					= false;
		spec.attribs[1].instanceDivisor				= 1;
		spec.attribs[1].useDefaultAttribute			= false;
		spec.attribs[1].additionalPositionAttribute	= true;

		// Instanced color
		spec.attribs[2].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
		spec.attribs[2].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
		spec.attribs[2].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.attribs[2].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
		spec.attribs[2].componentCount				= 3;
		spec.attribs[2].offset						= 0;
		spec.attribs[2].stride						= 0;
		spec.attribs[2].normalize					= false;
		spec.attribs[2].instanceDivisor				= 1;
		spec.attribs[2].useDefaultAttribute			= false;

		addTestIterations(test, spec, TYPE_INSTANCE_COUNT);

		this->addChild(test);
	}

	// Multiple attribute, second one default
	{
		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
		gls::DrawTestSpec	spec;

		spec.apiType							= glu::ApiType::es(3,1);
		spec.primitive							= m_primitive;
		spec.primitiveCount						= 5;
		spec.drawMethod							= m_method;
		spec.indexType							= m_indexType;
		spec.indexPointerOffset					= 0;
		spec.indexStorage						= m_indexStorage;
		spec.first								= 0;
		spec.indexMin							= 0;
		spec.indexMax							= 0;
		spec.instanceCount						= 1;
		spec.indirectOffset						= 0;

		spec.attribs.resize(2);

		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
		spec.attribs[0].componentCount			= 2;
		spec.attribs[0].offset					= 0;
		spec.attribs[0].stride					= 0;
		spec.attribs[0].normalize				= false;
		spec.attribs[0].instanceDivisor			= 0;
		spec.attribs[0].useDefaultAttribute		= false;

		struct IOPair
		{
			gls::DrawTestSpec::InputType  input;
			gls::DrawTestSpec::OutputType output;
			int							  componentCount;
		} iopairs[] =
		{
			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC2,  4 },
			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC4,  2 },
			{ gls::DrawTestSpec::INPUTTYPE_INT,          gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
			{ gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
		};

		for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
		{
			const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);

			spec.attribs[1].inputType			= iopairs[ioNdx].input;
			spec.attribs[1].outputType			= iopairs[ioNdx].output;
			spec.attribs[1].storage				= gls::DrawTestSpec::STORAGE_BUFFER;
			spec.attribs[1].usage				= gls::DrawTestSpec::USAGE_STATIC_DRAW;
			spec.attribs[1].componentCount		= iopairs[ioNdx].componentCount;
			spec.attribs[1].offset				= 0;
			spec.attribs[1].stride				= 0;
			spec.attribs[1].normalize			= false;
			spec.attribs[1].instanceDivisor		= 0;
			spec.attribs[1].useDefaultAttribute	= true;

			test->addIteration(spec, desc.c_str());
		}

		this->addChild(test);
	}
}

class IndexGroup : public TestCaseGroup
{
public:
									IndexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
									~IndexGroup		(void);

	void							init			(void);

private:
	gls::DrawTestSpec::DrawMethod	m_method;
};

IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
	: TestCaseGroup		(context, name, descr)
	, m_method			(drawMethod)
{
}

IndexGroup::~IndexGroup (void)
{
}

void IndexGroup::init (void)
{
	struct IndexTest
	{
		gls::DrawTestSpec::IndexType	type;
		int								offsets[3];
	};

	const IndexTest tests[] =
	{
		{ gls::DrawTestSpec::INDEXTYPE_BYTE,	{ 0, 1, -1 } },
		{ gls::DrawTestSpec::INDEXTYPE_SHORT,	{ 0, 2, -1 } },
		{ gls::DrawTestSpec::INDEXTYPE_INT,		{ 0, 4, -1 } },
	};

	gls::DrawTestSpec spec;
	genBasicSpec(spec, m_method);

	spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;

	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
	{
		const IndexTest&	indexTest	= tests[testNdx];

		const std::string	name		= std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
		const std::string	desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
		gls::DrawTest*		test		= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());

		spec.indexType			= indexTest.type;

		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
		{
			const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
			spec.indexPointerOffset	= indexTest.offsets[iterationNdx];
			test->addIteration(spec, iterationDesc.c_str());
		}

		addChild(test);
	}
}

class BaseVertexGroup : public TestCaseGroup
{
public:
									BaseVertexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
									~BaseVertexGroup	(void);

	void							init				(void);

private:
	gls::DrawTestSpec::DrawMethod	m_method;
};

BaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
	: TestCaseGroup		(context, name, descr)
	, m_method			(drawMethod)
{
}

BaseVertexGroup::~BaseVertexGroup (void)
{
}

void BaseVertexGroup::init (void)
{
	struct IndexTest
	{
		bool							positiveBase;
		gls::DrawTestSpec::IndexType	type;
		int								baseVertex[2];
	};

	const IndexTest tests[] =
	{
		{ true,  gls::DrawTestSpec::INDEXTYPE_BYTE,		{  1,  2 } },
		{ true,  gls::DrawTestSpec::INDEXTYPE_SHORT,	{  1,  2 } },
		{ true,  gls::DrawTestSpec::INDEXTYPE_INT,		{  1,  2 } },
		{ false, gls::DrawTestSpec::INDEXTYPE_BYTE,		{ -1, -2 } },
		{ false, gls::DrawTestSpec::INDEXTYPE_SHORT,	{ -1, -2 } },
		{ false, gls::DrawTestSpec::INDEXTYPE_INT,		{ -1, -2 } },
	};

	gls::DrawTestSpec spec;
	genBasicSpec(spec, m_method);

	spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;

	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
	{
		const IndexTest&	indexTest	= tests[testNdx];

		const std::string	name		= std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
		const std::string	desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
		gls::DrawTest*		test		= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());

		spec.indexType			= indexTest.type;

		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
		{
			const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
			spec.baseVertex	= indexTest.baseVertex[iterationNdx];
			test->addIteration(spec, iterationDesc.c_str());
		}

		addChild(test);
	}
}

class FirstGroup : public TestCaseGroup
{
public:
									FirstGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
									~FirstGroup		(void);

	void							init			(void);

private:
	gls::DrawTestSpec::DrawMethod	m_method;
};

FirstGroup::FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
	: TestCaseGroup		(context, name, descr)
	, m_method			(drawMethod)
{
}

FirstGroup::~FirstGroup (void)
{
}

void FirstGroup::init (void)
{
	const int firsts[] =
	{
		1, 3, 17
	};

	gls::DrawTestSpec spec;
	genBasicSpec(spec, m_method);

	for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx)
	{
		const std::string	name = std::string("first_") + de::toString(firsts[firstNdx]);
		const std::string	desc = std::string("first ") + de::toString(firsts[firstNdx]);
		gls::DrawTest*		test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());

		spec.first = firsts[firstNdx];

		addTestIterations(test, spec, TYPE_DRAW_COUNT);

		this->addChild(test);
	}
}

class MethodGroup : public TestCaseGroup
{
public:
									MethodGroup			(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
									~MethodGroup		(void);

	void							init				(void);

private:
	gls::DrawTestSpec::DrawMethod	m_method;
};

MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
	: TestCaseGroup		(context, name, descr)
	, m_method			(drawMethod)
{
}

MethodGroup::~MethodGroup (void)
{
}

void MethodGroup::init (void)
{
	const bool indexed		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT);
	const bool hasFirst		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT);

	const gls::DrawTestSpec::Primitive primitive[] =
	{
		gls::DrawTestSpec::PRIMITIVE_POINTS,
		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
		gls::DrawTestSpec::PRIMITIVE_LINES,
		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
	};

	if (hasFirst)
	{
		// First-tests
		this->addChild(new FirstGroup(m_context, "first", "First tests", m_method));
	}

	if (indexed)
	{
		// Index-tests
		this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
		this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
	}

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
	{
		const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
		const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);

		this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
	}
}

class GridProgram : public sglr::ShaderProgram
{
public:
			GridProgram		(void);

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

GridProgram::GridProgram (void)
	: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
							<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::VertexAttribute("a_offset", rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
							<< sglr::pdec::VertexSource("#version 310 es\n"
														"in highp vec4 a_position;\n"
														"in highp vec4 a_offset;\n"
														"in highp vec4 a_color;\n"
														"out highp vec4 v_color;\n"
														"void main(void)\n"
														"{\n"
														"	gl_Position = a_position + a_offset;\n"
														"	v_color = a_color;\n"
														"}\n")
							<< sglr::pdec::FragmentSource(
														"#version 310 es\n"
														"layout(location = 0) out highp vec4 dEQP_FragColor;\n"
														"in highp vec4 v_color;\n"
														"void main(void)\n"
														"{\n"
														"	dEQP_FragColor = v_color;\n"
														"}\n"))
{
}

void GridProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
{
	for (int ndx = 0; ndx < numPackets; ++ndx)
	{
		packets[ndx]->position = rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx) + rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
		packets[ndx]->outputs[0] = rr::readVertexAttribFloat(inputs[2], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
	}
}

void GridProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
{
	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
		rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx));
}

class InstancedGridRenderTest : public TestCase
{
public:
					InstancedGridRenderTest		(Context& context, const char* name, const char* desc, int gridSide, bool useIndices);
					~InstancedGridRenderTest	(void);

	IterateResult	iterate						(void);

private:
	void			renderTo					(sglr::Context& ctx, sglr::ShaderProgram& program, tcu::Surface& dst);

	const int		m_gridSide;
	const bool		m_useIndices;
};

InstancedGridRenderTest::InstancedGridRenderTest (Context& context, const char* name, const char* desc, int gridSide, bool useIndices)
	: TestCase		(context, name, desc)
	, m_gridSide	(gridSide)
	, m_useIndices	(useIndices)
{
}

InstancedGridRenderTest::~InstancedGridRenderTest (void)
{
}

InstancedGridRenderTest::IterateResult InstancedGridRenderTest::iterate (void)
{
	const int renderTargetWidth  = de::min(1024, m_context.getRenderTarget().getWidth());
	const int renderTargetHeight = de::min(1024, m_context.getRenderTarget().getHeight());

	sglr::GLContext ctx		(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS, tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight));
	tcu::Surface	surface	(renderTargetWidth, renderTargetHeight);
	GridProgram		program;

	// render

	renderTo(ctx, program, surface);

	// verify image
	// \note the green/yellow pattern is only for clarity. The test will only verify that all instances were drawn by looking for anything non-green/yellow.
	if (verifyImageYellowGreen(surface, m_testCtx.getLog()))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
	return STOP;
}

void InstancedGridRenderTest::renderTo (sglr::Context& ctx, sglr::ShaderProgram& program, tcu::Surface& dst)
{
	const tcu::Vec4 green	(0, 1, 0, 1);
	const tcu::Vec4 yellow	(1, 1, 0, 1);

	deUint32 vaoID			= 0;
	deUint32 positionBuf	= 0;
	deUint32 offsetBuf		= 0;
	deUint32 colorBuf		= 0;
	deUint32 indexBuf		= 0;
	deUint32 drawIndirectBuf= 0;
	deUint32 programID		= ctx.createProgram(&program);
	deInt32 posLocation		= ctx.getAttribLocation(programID, "a_position");
	deInt32 offsetLocation	= ctx.getAttribLocation(programID, "a_offset");
	deInt32 colorLocation	= ctx.getAttribLocation(programID, "a_color");

	float cellW	= 2.0f / (float)m_gridSide;
	float cellH	= 2.0f / (float)m_gridSide;
	const tcu::Vec4 vertexPositions[] =
	{
		tcu::Vec4(0,		0,		0, 1),
		tcu::Vec4(cellW,	0,		0, 1),
		tcu::Vec4(0,		cellH,	0, 1),

		tcu::Vec4(0,		cellH,	0, 1),
		tcu::Vec4(cellW,	0,		0, 1),
		tcu::Vec4(cellW,	cellH,	0, 1),
	};

	const deUint16 indices[] =
	{
		0, 4, 3,
		2, 1, 5
	};

	std::vector<tcu::Vec4> offsets;
	for (int x = 0; x < m_gridSide; ++x)
	for (int y = 0; y < m_gridSide; ++y)
		offsets.push_back(tcu::Vec4((float)x * cellW - 1.0f, (float)y * cellW - 1.0f, 0, 0));

	std::vector<tcu::Vec4> colors;
	for (int x = 0; x < m_gridSide; ++x)
	for (int y = 0; y < m_gridSide; ++y)
		colors.push_back(((x + y) % 2 == 0) ? (green) : (yellow));

	ctx.genVertexArrays(1, &vaoID);
	ctx.bindVertexArray(vaoID);

	ctx.genBuffers(1, &positionBuf);
	ctx.bindBuffer(GL_ARRAY_BUFFER, positionBuf);
	ctx.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
	ctx.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	ctx.vertexAttribDivisor(posLocation, 0);
	ctx.enableVertexAttribArray(posLocation);

	ctx.genBuffers(1, &offsetBuf);
	ctx.bindBuffer(GL_ARRAY_BUFFER, offsetBuf);
	ctx.bufferData(GL_ARRAY_BUFFER, offsets.size() * sizeof(tcu::Vec4), &offsets[0], GL_STATIC_DRAW);
	ctx.vertexAttribPointer(offsetLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	ctx.vertexAttribDivisor(offsetLocation, 1);
	ctx.enableVertexAttribArray(offsetLocation);

	ctx.genBuffers(1, &colorBuf);
	ctx.bindBuffer(GL_ARRAY_BUFFER, colorBuf);
	ctx.bufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(tcu::Vec4), &colors[0], GL_STATIC_DRAW);
	ctx.vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	ctx.vertexAttribDivisor(colorLocation, 1);
	ctx.enableVertexAttribArray(colorLocation);

	if (m_useIndices)
	{
		ctx.genBuffers(1, &indexBuf);
		ctx.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
		ctx.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	}

	ctx.genBuffers(1, &drawIndirectBuf);
	ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, drawIndirectBuf);

	if (m_useIndices)
	{
		DrawElementsCommand command;
		command.count				= 6;
		command.primCount			= m_gridSide * m_gridSide;
		command.firstIndex			= 0;
		command.baseVertex			= 0;
		command.reservedMustBeZero	= 0;

		ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(command), &command, GL_STATIC_DRAW);
	}
	else
	{
		DrawArraysCommand command;
		command.count				= 6;
		command.primCount			= m_gridSide * m_gridSide;
		command.first				= 0;
		command.reservedMustBeZero	= 0;

		ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(command), &command, GL_STATIC_DRAW);
	}

	ctx.clearColor(0, 0, 0, 1);
	ctx.clear(GL_COLOR_BUFFER_BIT);

	ctx.viewport(0, 0, dst.getWidth(), dst.getHeight());

	ctx.useProgram(programID);
	if (m_useIndices)
		ctx.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, DE_NULL);
	else
		ctx.drawArraysIndirect(GL_TRIANGLES, DE_NULL);
	ctx.useProgram(0);

	glu::checkError(ctx.getError(), "", __FILE__, __LINE__);

	ctx.deleteBuffers(1, &drawIndirectBuf);
	if (m_useIndices)
		ctx.deleteBuffers(1, &indexBuf);
	ctx.deleteBuffers(1, &colorBuf);
	ctx.deleteBuffers(1, &offsetBuf);
	ctx.deleteBuffers(1, &positionBuf);
	ctx.deleteVertexArrays(1, &vaoID);
	ctx.deleteProgram(programID);

	ctx.finish();
	ctx.readPixels(dst, 0, 0, dst.getWidth(), dst.getHeight());

	glu::checkError(ctx.getError(), "", __FILE__, __LINE__);
}

class InstancingGroup : public TestCaseGroup
{
public:
			InstancingGroup		(Context& context, const char* name, const char* descr);
			~InstancingGroup	(void);

	void	init				(void);
};

InstancingGroup::InstancingGroup (Context& context, const char* name, const char* descr)
	: TestCaseGroup	(context, name, descr)
{
}

InstancingGroup::~InstancingGroup (void)
{
}

void InstancingGroup::init (void)
{
	const int gridWidths[] =
	{
		2,
		5,
		10,
		32,
		100,
	};

	// drawArrays
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
	{
		const std::string name = std::string("draw_arrays_indirect_grid_") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
		const std::string desc = std::string("DrawArraysIndirect, Grid size ") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);

		this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], false));
	}

	// drawElements
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
	{
		const std::string name = std::string("draw_elements_indirect_grid_") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
		const std::string desc = std::string("DrawElementsIndirect, Grid size ") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);

		this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], true));
	}
}

class ComputeShaderGeneratedCase : public TestCase
{
public:
	enum DrawMethod
	{
		DRAWMETHOD_DRAWARRAYS,
		DRAWMETHOD_DRAWELEMENTS,
		DRAWMETHOD_LAST
	};

						ComputeShaderGeneratedCase	(Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int drawCallCount);
						~ComputeShaderGeneratedCase	(void);
	void				init						(void);
	void				deinit						(void);

	IterateResult		iterate						(void);
	std::string			genComputeSource			(bool computeCmd, bool computeData, bool computeIndices) const;

private:
	void				createDrawCommand			(void);
	void				createDrawData				(void);
	void				createDrawIndices			(void);

	virtual void		runComputeShader			(void) = 0;
	void				renderTo					(tcu::Surface& image);

protected:
	deUint32			calcDrawBufferSize			(void) const;
	deUint32			calcIndexBufferSize			(void) const;

	const DrawMethod	m_drawMethod;
	const bool			m_computeCmd;
	const bool			m_computeData;
	const bool			m_computeIndices;
	const int			m_commandSize;
	const int			m_numDrawCmds;
	const int			m_gridSize;

	glw::GLuint			m_cmdBufferID;
	glw::GLuint			m_dataBufferID;
	glw::GLuint			m_indexBufferID;

private:
	glu::ShaderProgram*	m_shaderProgram;
};

ComputeShaderGeneratedCase::ComputeShaderGeneratedCase (Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int drawCallCount)
	: TestCase			(context, name, desc)
	, m_drawMethod		(method)
	, m_computeCmd		(computeCmd)
	, m_computeData		(computeData)
	, m_computeIndices	(computeIndices)
	, m_commandSize		((method==DRAWMETHOD_DRAWARRAYS) ? ((int)sizeof(DrawArraysCommand)) : ((int)sizeof(DrawElementsCommand)))
	, m_numDrawCmds		(drawCallCount)
	, m_gridSize		(gridSize)
	, m_cmdBufferID		(0)
	, m_dataBufferID	(0)
	, m_indexBufferID	(0)
	, m_shaderProgram	(DE_NULL)
{
    const int triangleCount	= m_gridSize * m_gridSize * 2;

	DE_ASSERT(method < DRAWMETHOD_LAST);
	DE_ASSERT(!computeIndices || method == DRAWMETHOD_DRAWELEMENTS);
	DE_ASSERT(triangleCount % m_numDrawCmds == 0);
	DE_UNREF(triangleCount);
}

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

void ComputeShaderGeneratedCase::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// generate basic shader

	m_shaderProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_colorVertexShaderSource) << glu::FragmentSource(s_colorFragmentShaderSource));
	m_testCtx.getLog() << *m_shaderProgram;

	if (!m_shaderProgram->isOk())
		throw tcu::TestError("Failed to compile shader.");

	// gen buffers
	gl.genBuffers(1, &m_cmdBufferID);
	gl.genBuffers(1, &m_dataBufferID);
	gl.genBuffers(1, &m_indexBufferID);

	// check the SSBO buffers are of legal size
	{
		const deUint64	drawBufferElementSize	= sizeof(tcu::Vec4);
		const deUint64	indexBufferElementSize	= sizeof(deUint32);
		const int		commandBufferSize		= m_commandSize * m_numDrawCmds;
		deInt64			maxSSBOSize				= 0;

		gl.getInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxSSBOSize);

		if (m_computeData && (deUint64)calcDrawBufferSize()*drawBufferElementSize > (deUint64)maxSSBOSize)
			throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for vertex attrib buffers");
		if (m_computeIndices && (deUint64)calcIndexBufferSize()*indexBufferElementSize > (deUint64)maxSSBOSize)
			throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for index buffers");
		if (m_computeCmd && (deUint64)commandBufferSize > (deUint64)maxSSBOSize)
			throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for command buffers");
	}
}

void ComputeShaderGeneratedCase::deinit (void)
{
	if (m_cmdBufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_cmdBufferID);
		m_cmdBufferID = 0;
	}
	if (m_dataBufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_dataBufferID);
		m_dataBufferID = 0;
	}
	if (m_indexBufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBufferID);
		m_indexBufferID = 0;
	}

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

ComputeShaderGeneratedCase::IterateResult ComputeShaderGeneratedCase::iterate (void)
{
	const int				renderTargetWidth	= de::min(1024, m_context.getRenderTarget().getWidth());
	const int				renderTargetHeight	= de::min(1024, m_context.getRenderTarget().getHeight());
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	tcu::Surface			surface				(renderTargetWidth, renderTargetHeight);

	m_testCtx.getLog() << tcu::TestLog::Message << "Preparing to draw " << m_gridSize << " x " << m_gridSize << " grid." << tcu::TestLog::EndMessage;

	try
	{
		// Gen command buffer
		if (!m_computeCmd)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw command buffer." << tcu::TestLog::EndMessage;
			createDrawCommand();
		}

		// Gen data buffer
		if (!m_computeData)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw data buffer." << tcu::TestLog::EndMessage;
			createDrawData();
		}

		// Gen index buffer
		if (!m_computeIndices && m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw index buffer." << tcu::TestLog::EndMessage;
			createDrawIndices();
		}

		// Run compute shader
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "Filling following buffers using compute shader:\n"
				<< ((m_computeCmd)		? ("\tcommand buffer\n")	: (""))
				<< ((m_computeData)		? ("\tdata buffer\n")		: (""))
				<< ((m_computeIndices)	? ("\tindex buffer\n")		: (""))
				<< tcu::TestLog::EndMessage;
			runComputeShader();
		}

		// Ensure data is written to the buffers before we try to read it
		{
			const glw::GLuint barriers = ((m_computeCmd)     ? (GL_COMMAND_BARRIER_BIT)             : (0)) |
										 ((m_computeData)    ? (GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT) : (0)) |
										 ((m_computeIndices) ? (GL_ELEMENT_ARRAY_BARRIER_BIT)       : (0));

			m_testCtx.getLog() << tcu::TestLog::Message << "Memory barrier. Barriers = " << glu::getMemoryBarrierFlagsStr(barriers) << tcu::TestLog::EndMessage;
			gl.memoryBarrier(barriers);
		}

		// Draw from buffers

		m_testCtx.getLog() << tcu::TestLog::Message << "Drawing from buffers with " << m_numDrawCmds << " draw call(s)." << tcu::TestLog::EndMessage;
		renderTo(surface);
	}
	catch (glu::OutOfMemoryError&)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got GL_OUT_OF_MEMORY." << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Got GL_OUT_OF_MEMORY");
		m_testCtx.setTerminateAfter(true); // Do not rely on implementation to be able to recover from OOM
		return STOP;
	}


	// verify image
	// \note the green/yellow pattern is only for clarity. The test will only verify that all grid cells were drawn by looking for anything non-green/yellow.
	if (verifyImageYellowGreen(surface, m_testCtx.getLog()))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
	return STOP;
}

std::string ComputeShaderGeneratedCase::genComputeSource (bool computeCmd, bool computeData, bool computeIndices) const
{
	const int cmdLayoutBinding				= 0;
	const int dataLayoutBinding				= (computeCmd) ? (1) : (0);
	const int indexLayoutBinding			= (computeCmd && computeData) ? (2) : (computeCmd || computeData) ? (1) : (0);

	std::ostringstream buf;

	buf << "#version 310 es\n\n"
		<< "precision highp int;\n"
		<< "precision highp float;\n\n";

	if (computeCmd && m_drawMethod==DRAWMETHOD_DRAWARRAYS)
		buf	<< "struct DrawArraysIndirectCommand {\n"
			<< "    uint count;\n"
			<< "    uint primCount;\n"
			<< "    uint first;\n"
			<< "    uint reservedMustBeZero;\n"
			<< "};\n\n";
	else if (computeCmd && m_drawMethod==DRAWMETHOD_DRAWELEMENTS)
		buf	<< "struct DrawElementsIndirectCommand {\n"
			<< "    uint count;\n"
			<< "    uint primCount;\n"
			<< "    uint firstIndex;\n"
			<< "    int  baseVertex;\n"
			<< "    uint reservedMustBeZero;\n"
			<< "};\n\n";

	buf << "layout(local_size_x = 1, local_size_y = 1) in;\n"
		<< "layout(std430) buffer;\n\n";

	if (computeCmd)
		buf	<< "layout(binding = " << cmdLayoutBinding << ") writeonly buffer CommandBuffer {\n"
			<< "    " << ((m_drawMethod==DRAWMETHOD_DRAWARRAYS) ? ("DrawArraysIndirectCommand") : ("DrawElementsIndirectCommand")) << " commands[];\n"
			<< "};\n";
	if (computeData)
		buf	<< "layout(binding = " << dataLayoutBinding << ") writeonly buffer DataBuffer {\n"
			<< "    vec4 attribs[];\n"
			<< "};\n";
	if (computeIndices)
		buf	<< "layout(binding = " << indexLayoutBinding << ") writeonly buffer IndexBuffer {\n"
			<< "    uint indices[];\n"
			<< "};\n";

	buf	<< "\n"
		<< "void main() {\n"
		<< "    const uint gridSize      = " << m_gridSize << "u;\n"
		<< "    const uint triangleCount = gridSize * gridSize * 2u;\n"
		<< "\n";

	if (computeCmd)
	{
		buf	<< "    // command\n"
			<< "    if (gl_GlobalInvocationID.x < " << m_numDrawCmds << "u && gl_GlobalInvocationID.y == 0u && gl_GlobalInvocationID.z == 0u) {\n"
			<< "        const uint numDrawCallTris = triangleCount / " << m_numDrawCmds << "u;\n"
			<< "        uint firstTri              = gl_GlobalInvocationID.x * numDrawCallTris;\n\n"
			<< "        commands[gl_GlobalInvocationID.x].count                 = numDrawCallTris*3u;\n"
			<< "        commands[gl_GlobalInvocationID.x].primCount             = 1u;\n";

		if (m_drawMethod==DRAWMETHOD_DRAWARRAYS)
		{
			buf	<< "        commands[gl_GlobalInvocationID.x].first                 = firstTri*3u;\n";
		}
		else if (m_drawMethod==DRAWMETHOD_DRAWELEMENTS)
		{
			buf	<< "        commands[gl_GlobalInvocationID.x].firstIndex            = firstTri*3u;\n";
			buf	<< "        commands[gl_GlobalInvocationID.x].baseVertex            = 0;\n";
		}

		buf	<< "        commands[gl_GlobalInvocationID.x].reservedMustBeZero    = 0u;\n"
			<< "    }\n"
			<< "\n";
	}

	if (computeData)
	{
		buf	<< "    // vertex attribs\n"
			<< "    const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
			<< "    const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n";

		if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
		{
			buf	<< "    if (gl_GlobalInvocationID.x < gridSize && gl_GlobalInvocationID.y < gridSize && gl_GlobalInvocationID.z == 0u) {\n"
				<< "        uint        y           = gl_GlobalInvocationID.x;\n"
				<< "        uint        x           = gl_GlobalInvocationID.y;\n"
				<< "        float       posX        = (float(x) / float(gridSize)) * 2.0 - 1.0;\n"
				<< "        float       posY        = (float(y) / float(gridSize)) * 2.0 - 1.0;\n"
				<< "        const float cellSize    = 2.0 / float(gridSize);\n"
				<< "        vec4        color       = ((x + y)%2u != 0u) ? (yellow) : (green);\n"
				<< "\n"
				<< "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 0u] = vec4(posX,            posY,            0.0, 1.0);\n"
				<< "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 0u] = vec4(posX + cellSize, posY,            0.0, 1.0);\n"
				<< "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 0u] = vec4(posX + cellSize, posY + cellSize, 0.0, 1.0);\n"
				<< "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 0u] = vec4(posX,            posY,            0.0, 1.0);\n"
				<< "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 0u] = vec4(posX + cellSize, posY + cellSize, 0.0, 1.0);\n"
				<< "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 0u] = vec4(posX,            posY + cellSize, 0.0, 1.0);\n"
				<< "\n"
				<< "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 1u] = color;\n"
				<< "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 1u] = color;\n"
				<< "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 1u] = color;\n"
				<< "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 1u] = color;\n"
				<< "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 1u] = color;\n"
				<< "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 1u] = color;\n"
				<< "    }\n";
		}
		else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
		{
			buf	<< "    if (gl_GlobalInvocationID.x < gridSize+1u && gl_GlobalInvocationID.y < gridSize+1u && gl_GlobalInvocationID.z == 0u) {\n"
				<< "        uint        y           = gl_GlobalInvocationID.x;\n"
				<< "        uint        x           = gl_GlobalInvocationID.y;\n"
				<< "        float       posX        = (float(x) / float(gridSize)) * 2.0 - 1.0;\n"
				<< "        float       posY        = (float(y) / float(gridSize)) * 2.0 - 1.0;\n"
				<< "\n"
				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 0u] = vec4(posX, posY, 0.0, 1.0);\n"
				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 1u] = green;\n"
				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 2u] = vec4(posX, posY, 0.0, 1.0);\n"
				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 3u] = yellow;\n"
				<< "    }\n";
		}

		buf << "\n";
	}

	if (computeIndices)
	{
		buf	<< "    // indices\n"
			<< "    if (gl_GlobalInvocationID.x < gridSize && gl_GlobalInvocationID.y < gridSize && gl_GlobalInvocationID.z == 0u) {\n"
			<< "        uint    y       = gl_GlobalInvocationID.x;\n"
			<< "        uint    x       = gl_GlobalInvocationID.y;\n"
			<< "        uint    color   = ((x + y)%2u);\n"
			<< "\n"
			<< "        indices[(y * gridSize + x) * 6u + 0u] = ((y+0u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
			<< "        indices[(y * gridSize + x) * 6u + 1u] = ((y+1u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
			<< "        indices[(y * gridSize + x) * 6u + 2u] = ((y+1u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
			<< "        indices[(y * gridSize + x) * 6u + 3u] = ((y+0u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
			<< "        indices[(y * gridSize + x) * 6u + 4u] = ((y+1u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
			<< "        indices[(y * gridSize + x) * 6u + 5u] = ((y+0u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
			<< "    }\n"
			<< "\n";
	}

	buf	<< "}\n";

	return buf.str();
}

void ComputeShaderGeneratedCase::createDrawCommand (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	const int				triangleCount	= m_gridSize * m_gridSize * 2;
	const deUint32			numDrawCallTris	= triangleCount / m_numDrawCmds;

	if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
	{
		std::vector<DrawArraysCommand> cmds;

		for (int ndx = 0; ndx < m_numDrawCmds; ++ndx)
		{
			const deUint32				firstTri = ndx * numDrawCallTris;
			DrawArraysCommand			data;

			data.count					= numDrawCallTris*3;
			data.primCount				= 1;
			data.first					= firstTri*3;
			data.reservedMustBeZero		= 0;

			cmds.push_back(data);
		}

		DE_ASSERT((int)(sizeof(DrawArraysCommand)*cmds.size()) == m_numDrawCmds * m_commandSize);

		gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, (glw::GLsizeiptr)(sizeof(DrawArraysCommand)*cmds.size()), &cmds[0], GL_STATIC_DRAW);
	}
	else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
	{
		std::vector<DrawElementsCommand> cmds;

		for (int ndx = 0; ndx < m_numDrawCmds; ++ndx)
		{
			const deUint32			firstTri = ndx * numDrawCallTris;
			DrawElementsCommand		data;

			data.count				= numDrawCallTris*3;
			data.primCount			= 1;
			data.firstIndex			= firstTri*3;
			data.baseVertex			= 0;
			data.reservedMustBeZero	= 0;

			cmds.push_back(data);
		}

		DE_ASSERT((int)(sizeof(DrawElementsCommand)*cmds.size()) == m_numDrawCmds * m_commandSize);

		gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, (glw::GLsizeiptr)(sizeof(DrawElementsCommand)*cmds.size()), &cmds[0], GL_STATIC_DRAW);
	}
	else
		DE_ASSERT(false);

	glu::checkError(gl.getError(), "create draw command", __FILE__, __LINE__);
}

void ComputeShaderGeneratedCase::createDrawData (void)
{
	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 glw::Functions&	gl		= m_context.getRenderContext().getFunctions();

	if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
	{
		// Store elements in the order they are drawn. Interleave color.
		std::vector<tcu::Vec4> buffer(m_gridSize*m_gridSize*6*2);

		DE_ASSERT(buffer.size() == calcDrawBufferSize());

		for (int y = 0; y < m_gridSize; ++y)
		for (int x = 0; x < m_gridSize; ++x)
		{
			const float			posX		= ((float)x / (float)m_gridSize) * 2.0f - 1.0f;
			const float			posY		= ((float)y / (float)m_gridSize) * 2.0f - 1.0f;
			const float			cellSize	= 2.0f / (float)m_gridSize;
			const tcu::Vec4&	color		= ((x + y)%2) ? (yellow) : (green);

			buffer[((y * m_gridSize + x) * 6 + 0) * 2 + 0] = tcu::Vec4(posX,			posY,				0.0f, 1.0f);
			buffer[((y * m_gridSize + x) * 6 + 1) * 2 + 0] = tcu::Vec4(posX + cellSize,	posY,				0.0f, 1.0f);
			buffer[((y * m_gridSize + x) * 6 + 2) * 2 + 0] = tcu::Vec4(posX + cellSize,	posY + cellSize,	0.0f, 1.0f);
			buffer[((y * m_gridSize + x) * 6 + 3) * 2 + 0] = tcu::Vec4(posX,			posY,				0.0f, 1.0f);
			buffer[((y * m_gridSize + x) * 6 + 4) * 2 + 0] = tcu::Vec4(posX + cellSize, posY + cellSize,	0.0f, 1.0f);
			buffer[((y * m_gridSize + x) * 6 + 5) * 2 + 0] = tcu::Vec4(posX,			posY + cellSize,	0.0f, 1.0f);

			buffer[((y * m_gridSize + x) * 6 + 0) * 2 + 1] = color;
			buffer[((y * m_gridSize + x) * 6 + 1) * 2 + 1] = color;
			buffer[((y * m_gridSize + x) * 6 + 2) * 2 + 1] = color;
			buffer[((y * m_gridSize + x) * 6 + 3) * 2 + 1] = color;
			buffer[((y * m_gridSize + x) * 6 + 4) * 2 + 1] = color;
			buffer[((y * m_gridSize + x) * 6 + 5) * 2 + 1] = color;
		}

		gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
		gl.bufferData(GL_ARRAY_BUFFER, (int)(buffer.size() * sizeof(tcu::Vec4)), buffer[0].getPtr(), GL_STATIC_DRAW);
	}
	else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
	{
		// Elements are indexed by index buffer. Interleave color. Two vertices per position since 2 colors

		std::vector<tcu::Vec4> buffer((m_gridSize+1)*(m_gridSize+1)*4);

		DE_ASSERT(buffer.size() == calcDrawBufferSize());

		for (int y = 0; y < m_gridSize+1; ++y)
		for (int x = 0; x < m_gridSize+1; ++x)
		{
			const float			posX		= ((float)x / (float)m_gridSize) * 2.0f - 1.0f;
			const float			posY		= ((float)y / (float)m_gridSize) * 2.0f - 1.0f;

			buffer[(y * (m_gridSize+1) + x) * 4 + 0] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
			buffer[(y * (m_gridSize+1) + x) * 4 + 1] = green;
			buffer[(y * (m_gridSize+1) + x) * 4 + 2] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
			buffer[(y * (m_gridSize+1) + x) * 4 + 3] = yellow;
		}

		gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
		gl.bufferData(GL_ARRAY_BUFFER, (int)(buffer.size() * sizeof(tcu::Vec4)), buffer[0].getPtr(), GL_STATIC_DRAW);
	}
	else
		DE_ASSERT(false);

	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
}

void ComputeShaderGeneratedCase::createDrawIndices (void)
{
	DE_ASSERT(m_drawMethod == DRAWMETHOD_DRAWELEMENTS);

	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	std::vector<deUint32>	buffer	(m_gridSize*m_gridSize*6);

	DE_ASSERT(buffer.size() == calcIndexBufferSize());

	for (int y = 0; y < m_gridSize; ++y)
	for (int x = 0; x < m_gridSize; ++x)
	{
		const int color = ((x + y)%2);

		buffer[(y * m_gridSize + x) * 6 + 0] = ((y+0) * (m_gridSize+1) + (x+0)) * 2 + color;
		buffer[(y * m_gridSize + x) * 6 + 1] = ((y+1) * (m_gridSize+1) + (x+0)) * 2 + color;
		buffer[(y * m_gridSize + x) * 6 + 2] = ((y+1) * (m_gridSize+1) + (x+1)) * 2 + color;
		buffer[(y * m_gridSize + x) * 6 + 3] = ((y+0) * (m_gridSize+1) + (x+0)) * 2 + color;
		buffer[(y * m_gridSize + x) * 6 + 4] = ((y+1) * (m_gridSize+1) + (x+1)) * 2 + color;
		buffer[(y * m_gridSize + x) * 6 + 5] = ((y+0) * (m_gridSize+1) + (x+1)) * 2 + color;
	}

	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferID);
	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (int)(buffer.size() * sizeof(deUint32)), &buffer[0], GL_STATIC_DRAW);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
}

void ComputeShaderGeneratedCase::renderTo (tcu::Surface& dst)
{
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	const deInt32			positionLoc = gl.getAttribLocation(m_shaderProgram->getProgram(), "a_position");
	const deInt32			colorLoc	= gl.getAttribLocation(m_shaderProgram->getProgram(), "a_color");
	deUint32				vaoID		= 0;

	gl.genVertexArrays(1, &vaoID);
	gl.bindVertexArray(vaoID);

	// Setup buffers

	gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
	gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 8 * (int)sizeof(float), DE_NULL);
	gl.vertexAttribPointer(colorLoc,    4, GL_FLOAT, GL_FALSE, 8 * (int)sizeof(float), ((const deUint8*)DE_NULL) + 4*sizeof(float));
	gl.enableVertexAttribArray(positionLoc);
	gl.enableVertexAttribArray(colorLoc);

	DE_ASSERT(positionLoc != -1);
	DE_ASSERT(colorLoc != -1);

	if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferID);

	gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);

	// draw

	gl.clearColor(0, 0, 0, 1);
	gl.clear(GL_COLOR_BUFFER_BIT);
	gl.viewport(0, 0, dst.getWidth(), dst.getHeight());

	gl.useProgram(m_shaderProgram->getProgram());
	for (int drawCmdNdx = 0; drawCmdNdx < m_numDrawCmds; ++drawCmdNdx)
	{
		const void* offset = ((deUint8*)DE_NULL) + drawCmdNdx*m_commandSize;

		if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
			gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, offset);
		else if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
			gl.drawArraysIndirect(GL_TRIANGLES, offset);
		else
			DE_ASSERT(DE_FALSE);
	}
	gl.useProgram(0);

	// free

	gl.deleteVertexArrays(1, &vaoID);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	gl.finish();
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
}

deUint32 ComputeShaderGeneratedCase::calcDrawBufferSize (void) const
{
	// returns size in "vec4"s
	if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
		return m_gridSize*m_gridSize*6*2;
	else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
		return (m_gridSize+1)*(m_gridSize+1)*4;
	else
		DE_ASSERT(DE_FALSE);

	return 0;
}

deUint32 ComputeShaderGeneratedCase::calcIndexBufferSize (void) const
{
	if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
		return m_gridSize*m_gridSize*6;
	else
		return 0;
}

class ComputeShaderGeneratedCombinedCase : public ComputeShaderGeneratedCase
{
public:
						ComputeShaderGeneratedCombinedCase	(Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls);
						~ComputeShaderGeneratedCombinedCase	(void);

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

private:
	void				runComputeShader					(void);

	glu::ShaderProgram*	m_computeProgram;
};

ComputeShaderGeneratedCombinedCase::ComputeShaderGeneratedCombinedCase (Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls)
	: ComputeShaderGeneratedCase(context, name, desc, method, computeCmd, computeData, computeIndices, gridSize, numDrawCalls)
	, m_computeProgram			(DE_NULL)
{
}

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

void ComputeShaderGeneratedCombinedCase::init (void)
{
	// generate compute shader

	m_computeProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genComputeSource(m_computeCmd, m_computeData, m_computeIndices)));
	m_testCtx.getLog() << *m_computeProgram;

	if (!m_computeProgram->isOk())
		throw tcu::TestError("Failed to compile compute shader.");

	// init parent
	ComputeShaderGeneratedCase::init();
}

void ComputeShaderGeneratedCombinedCase::deinit (void)
{
	// deinit parent
	ComputeShaderGeneratedCase::deinit();

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

void ComputeShaderGeneratedCombinedCase::runComputeShader (void)
{
	const glw::Functions&	gl									= m_context.getRenderContext().getFunctions();
	const bool				indexed								= (m_drawMethod == DRAWMETHOD_DRAWELEMENTS);
	const tcu::IVec3		nullSize							(0, 0, 0);
	const tcu::IVec3		commandDispatchSize					= (m_computeCmd)				? (tcu::IVec3(m_numDrawCmds, 1, 1))				: (nullSize);
	const tcu::IVec3		drawElementsDataBufferDispatchSize	= (m_computeData)				? (tcu::IVec3(m_gridSize+1, m_gridSize+1, 1))	: (nullSize);
	const tcu::IVec3		drawArraysDataBufferDispatchSize	= (m_computeData)				? (tcu::IVec3(m_gridSize,   m_gridSize,   1))	: (nullSize);
	const tcu::IVec3		indexBufferDispatchSize				= (m_computeIndices && indexed)	? (tcu::IVec3(m_gridSize,   m_gridSize,   1))	: (nullSize);

	const tcu::IVec3		dataBufferDispatchSize				= (m_drawMethod == DRAWMETHOD_DRAWELEMENTS) ? (drawElementsDataBufferDispatchSize) : (drawArraysDataBufferDispatchSize);
	const tcu::IVec3		dispatchSize						= tcu::max(tcu::max(commandDispatchSize, dataBufferDispatchSize), indexBufferDispatchSize);

	gl.useProgram(m_computeProgram->getProgram());
	glu::checkError(gl.getError(), "use compute shader", __FILE__, __LINE__);

	// setup buffers

	if (m_computeCmd)
	{
		const int			bindingPoint	= 0;
		const int			bufferSize		= m_commandSize * m_numDrawCmds;

		m_testCtx.getLog() << tcu::TestLog::Message << "Binding command buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_cmdBufferID);

		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for command buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
	}

	if (m_computeData)
	{
		const int			bindingPoint	= (m_computeCmd) ? (1) : (0);
		const int			bufferSize		= (int)(calcDrawBufferSize()*sizeof(tcu::Vec4));

		m_testCtx.getLog() << tcu::TestLog::Message << "Binding data buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_dataBufferID);

		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for data buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
	}

	if (m_computeIndices)
	{
		const int			bindingPoint	= (m_computeCmd && m_computeData) ? (2) : (m_computeCmd || m_computeData) ? (1) : (0);
		const int			bufferSize		= (int)(calcIndexBufferSize()*sizeof(deUint32));

		m_testCtx.getLog() << tcu::TestLog::Message << "Binding index buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_indexBufferID);

		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for index buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
	}

	glu::checkError(gl.getError(), "setup buffers", __FILE__, __LINE__);

	// calculate

	m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching compute, size = " << dispatchSize << tcu::TestLog::EndMessage;
	gl.dispatchCompute(dispatchSize.x(), dispatchSize.y(), dispatchSize.z());

	glu::checkError(gl.getError(), "calculate", __FILE__, __LINE__);
}

class ComputeShaderGeneratedSeparateCase : public ComputeShaderGeneratedCase
{
public:
						ComputeShaderGeneratedSeparateCase	(Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls);
						~ComputeShaderGeneratedSeparateCase	(void);

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

private:
	std::string			genCmdComputeSource					(void);
	std::string			genDataComputeSource				(void);
	std::string			genIndexComputeSource				(void);
	void				runComputeShader					(void);

	glu::ShaderProgram*	m_computeCmdProgram;
	glu::ShaderProgram*	m_computeDataProgram;
	glu::ShaderProgram*	m_computeIndicesProgram;
};

ComputeShaderGeneratedSeparateCase::ComputeShaderGeneratedSeparateCase (Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls)
	: ComputeShaderGeneratedCase	(context, name, desc, method, computeCmd, computeData, computeIndices, gridSize, numDrawCalls)
	, m_computeCmdProgram			(DE_NULL)
	, m_computeDataProgram			(DE_NULL)
	, m_computeIndicesProgram		(DE_NULL)
{
}

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

void ComputeShaderGeneratedSeparateCase::init (void)
{
	// generate cmd compute shader

	if (m_computeCmd)
	{
		m_computeCmdProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genCmdComputeSource()));
		m_testCtx.getLog() << *m_computeCmdProgram;

		if (!m_computeCmdProgram->isOk())
			throw tcu::TestError("Failed to compile command compute shader.");
	}

	// generate data compute shader

	if (m_computeData)
	{
		m_computeDataProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genDataComputeSource()));
		m_testCtx.getLog() << *m_computeDataProgram;

		if (!m_computeDataProgram->isOk())
			throw tcu::TestError("Failed to compile data compute shader.");
	}

	// generate index compute shader

	if (m_computeIndices)
	{
		m_computeIndicesProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genIndexComputeSource()));
		m_testCtx.getLog() << *m_computeIndicesProgram;

		if (!m_computeIndicesProgram->isOk())
			throw tcu::TestError("Failed to compile data compute shader.");
	}

	// init parent
	ComputeShaderGeneratedCase::init();
}

void ComputeShaderGeneratedSeparateCase::deinit (void)
{
	// deinit parent
	ComputeShaderGeneratedCase::deinit();

	if (m_computeCmdProgram)
	{
		delete m_computeCmdProgram;
		m_computeCmdProgram = DE_NULL;
	}
	if (m_computeDataProgram)
	{
		delete m_computeDataProgram;
		m_computeDataProgram = DE_NULL;
	}
	if (m_computeIndicesProgram)
	{
		delete m_computeIndicesProgram;
		m_computeIndicesProgram = DE_NULL;
	}
}

std::string ComputeShaderGeneratedSeparateCase::genCmdComputeSource (void)
{
	return ComputeShaderGeneratedCase::genComputeSource(true, false, false);
}

std::string ComputeShaderGeneratedSeparateCase::genDataComputeSource (void)
{
	return ComputeShaderGeneratedCase::genComputeSource(false, true, false);
}

std::string ComputeShaderGeneratedSeparateCase::genIndexComputeSource (void)
{
	return ComputeShaderGeneratedCase::genComputeSource(false, false, true);
}

void ComputeShaderGeneratedSeparateCase::runComputeShader (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// Compute command

	if (m_computeCmd)
	{
		const int				bindingPoint			= 0;
		const tcu::IVec3		commandDispatchSize		(m_numDrawCmds, 1, 1);
		const int				bufferSize				= m_commandSize * m_numDrawCmds;

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

		// setup buffers

		m_testCtx.getLog() << tcu::TestLog::Message << "Binding command buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_cmdBufferID);

		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for command buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);

		// calculate

		m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching command compute, size = " << commandDispatchSize << tcu::TestLog::EndMessage;
		gl.dispatchCompute(commandDispatchSize.x(), commandDispatchSize.y(), commandDispatchSize.z());

		glu::checkError(gl.getError(), "calculate cmd", __FILE__, __LINE__);
	}

	// Compute data

	if (m_computeData)
	{
		const int				bindingPoint						= 0;
		const tcu::IVec3		drawElementsDataBufferDispatchSize	(m_gridSize+1, m_gridSize+1, 1);
		const tcu::IVec3		drawArraysDataBufferDispatchSize	(m_gridSize,   m_gridSize,   1);
		const tcu::IVec3		dataBufferDispatchSize				= (m_drawMethod == DRAWMETHOD_DRAWELEMENTS) ? (drawElementsDataBufferDispatchSize) : (drawArraysDataBufferDispatchSize);
		const int				bufferSize							= (int)(calcDrawBufferSize()*sizeof(tcu::Vec4));

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

		// setup buffers

		m_testCtx.getLog() << tcu::TestLog::Message << "Binding data buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_dataBufferID);

		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for data buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);

		// calculate

		m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching data compute, size = " << dataBufferDispatchSize << tcu::TestLog::EndMessage;
		gl.dispatchCompute(dataBufferDispatchSize.x(), dataBufferDispatchSize.y(), dataBufferDispatchSize.z());

		glu::checkError(gl.getError(), "calculate data", __FILE__, __LINE__);
	}

	// Compute indices

	if (m_computeIndices)
	{
		const int				bindingPoint				= 0;
		const tcu::IVec3		indexBufferDispatchSize		(m_gridSize, m_gridSize, 1);
		const int				bufferSize					= (int)(calcIndexBufferSize()*sizeof(deUint32));

		DE_ASSERT(m_drawMethod == DRAWMETHOD_DRAWELEMENTS);

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

		// setup buffers

		m_testCtx.getLog() << tcu::TestLog::Message << "Binding index buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_indexBufferID);

		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for index buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);

		// calculate

		m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching index compute, size = " << indexBufferDispatchSize << tcu::TestLog::EndMessage;
		gl.dispatchCompute(indexBufferDispatchSize.x(), indexBufferDispatchSize.y(), indexBufferDispatchSize.z());

		glu::checkError(gl.getError(), "calculate indices", __FILE__, __LINE__);
	}

	glu::checkError(gl.getError(), "post dispatch", __FILE__, __LINE__);
}

class ComputeShaderGeneratedGroup : public TestCaseGroup
{
public:
			ComputeShaderGeneratedGroup		(Context& context, const char* name, const char* descr);
			~ComputeShaderGeneratedGroup	(void);

	void	init							(void);
};

ComputeShaderGeneratedGroup::ComputeShaderGeneratedGroup (Context& context, const char* name, const char* descr)
	: TestCaseGroup	(context, name, descr)
{
}

ComputeShaderGeneratedGroup::~ComputeShaderGeneratedGroup (void)
{
}

void ComputeShaderGeneratedGroup::init (void)
{
	const int					gridSize		= 8;
	tcu::TestCaseGroup* const	separateGroup	= new tcu::TestCaseGroup(m_testCtx, "separate", "Use separate compute shaders for each buffer");
	tcu::TestCaseGroup* const	combinedGroup	= new tcu::TestCaseGroup(m_testCtx, "combined", "Use combined compute shader for all buffers");
	tcu::TestCaseGroup* const	largeGroup		= new tcu::TestCaseGroup(m_testCtx, "large",   "Draw shapes with large buffers");

	this->addChild(separateGroup);
	this->addChild(combinedGroup);
	this->addChild(largeGroup);

	// .separate
	{
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawarrays_compute_cmd",							"Command from compute shader",						ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		true,	false,	false,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawarrays_compute_data",						"Data from compute shader",							ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		false,	true,	false,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawarrays_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		true,	true,	false,	gridSize,	1));

		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd",						"Command from compute shader",						ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	false,	false,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_data",						"Data from compute shader",							ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	true,	false,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_indices",					"Indices from compute shader",						ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	false,	true,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	false,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd_and_indices",			"Command and indices from compute shader",			ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	false,	true,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_data_and_indices",			"Data and indices from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	true,	true,	gridSize,	1));
		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd_and_data_and_indices",	"Command, data and indices from compute shader",	ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	true,	gridSize,	1));
	}

	// .combined
	{
		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawarrays_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		true,	true,	false,	gridSize,	1));
		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	false,	gridSize,	1));
		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_cmd_and_indices",			"Command and indices from compute shader",			ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	false,	true,	gridSize,	1));
		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_data_and_indices",			"Data and indices from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	true,	true,	gridSize,	1));
		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_cmd_and_data_and_indices",	"Command, data and indices from compute shader",	ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	true,	gridSize,	1));
	}

	// .large
	{
		struct TestSpec
		{
			int gridSize;
			int numDrawCommands;
		};
		struct TestMethod
		{
			ComputeShaderGeneratedCase::DrawMethod method;
			bool                                   separateCompute;
		};

		static const TestSpec specs[] =
		{
			{ 100,	1 },		// !< drawArrays array size ~ 1.9 MB
			{ 200,	1 },		// !< drawArrays array size ~ 7.7 MB
			{ 500,	1 },		// !< drawArrays array size ~ 48 MB
			{ 1000,	1 },		// !< drawArrays array size ~ 192 MB
			{ 1200,	1 },		// !< drawArrays array size ~ 277 MB
			{ 1500,	1 },		// !< drawArrays array size ~ 430 MB

			{ 100,	8 },		// !< drawArrays array size ~ 1.9 MB
			{ 200,	8 },		// !< drawArrays array size ~ 7.7 MB
			{ 500,	8 },		// !< drawArrays array size ~ 48 MB
			{ 1000,	8 },		// !< drawArrays array size ~ 192 MB
			{ 1200,	8 },		// !< drawArrays array size ~ 277 MB
			{ 1500,	8 },		// !< drawArrays array size ~ 430 MB

			{ 100,	200  },		// !< 50 cells per draw call
			{ 200,	800  },		// !< 50 cells per draw call
			{ 500,	2500 },		// !< 100 cells per draw call
			{ 1000,	5000 },		// !< 250 cells per draw call
		};
		static const TestMethod methods[] =
		{
			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,	true	},
			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,	false	},
			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true	},
			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false	},
		};

		for (int methodNdx = 0; methodNdx < DE_LENGTH_OF_ARRAY(methods); ++methodNdx)
		for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); ++specNdx)
		{
			const std::string name = std::string("")
									+ ((methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS) ? ("drawarrays") : ("drawelements"))
									+ ((methods[methodNdx].separateCompute) ? ("_separate") : ("_combined"))
									+ "_grid_" + de::toString(specs[specNdx].gridSize) + "x" + de::toString(specs[specNdx].gridSize)
									+ "_drawcount_" + de::toString(specs[specNdx].numDrawCommands);

			const std::string desc = std::string("Draw grid with ")
									+ ((methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS) ? ("drawarrays indirect") : ("drawelements indirect"))
									+ " calculating buffers in " + ((methods[methodNdx].separateCompute) ? ("separate") : ("combined")) + " compute shader."
									+ " Grid size is " + de::toString(specs[specNdx].gridSize) + "x" + de::toString(specs[specNdx].gridSize)
									+ ", draw count is "  + de::toString(specs[specNdx].numDrawCommands);

			const bool computeIndices = (methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS);

			if (methods[methodNdx].separateCompute)
				largeGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, name.c_str(), desc.c_str(), methods[methodNdx].method, false, true, computeIndices, specs[specNdx].gridSize, specs[specNdx].numDrawCommands));
			else
				largeGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, name.c_str(), desc.c_str(), methods[methodNdx].method, false, true, computeIndices, specs[specNdx].gridSize, specs[specNdx].numDrawCommands));
		}
	}
}

class RandomGroup : public TestCaseGroup
{
public:
			RandomGroup		(Context& context, const char* name, const char* descr);
			~RandomGroup	(void);

	void	init			(void);
};

template <int SIZE>
struct UniformWeightArray
{
	float weights[SIZE];

	UniformWeightArray (void)
	{
		for (int i=0; i<SIZE; ++i)
			weights[i] = 1.0f;
	}
};

RandomGroup::RandomGroup (Context& context, const char* name, const char* descr)
	: TestCaseGroup	(context, name, descr)
{
}

RandomGroup::~RandomGroup (void)
{
}

void RandomGroup::init (void)
{
	const int	numAttempts				= 100;

	const int	attribCounts[]			= { 1,   2,   5 };
	const float	attribWeights[]			= { 30, 10,   1 };
	const int	primitiveCounts[]		= { 1,   5,  64 };
	const float	primitiveCountWeights[]	= { 20, 10,   1 };
	const int	indexOffsets[]			= { 0,   7,  13 };
	const float	indexOffsetWeights[]	= { 20, 20,   1 };
	const int	firsts[]				= { 0,   7,  13 };
	const float	firstWeights[]			= { 20, 20,   1 };

	const int	instanceCounts[]		= { 1,   2,  16,  17 };
	const float	instanceWeights[]		= { 20, 10,   5,   1 };
	const int	indexMins[]				= { 0,   1,   3,   8 };
	const int	indexMaxs[]				= { 4,   8, 128, 257 };
	const float	indexWeights[]			= { 50, 50,  50,  50 };
	const int	offsets[]				= { 0,   1,   5,  12 };
	const float	offsetWeights[]			= { 50, 10,  10,  10 };
	const int	strides[]				= { 0,   7,  16,  17 };
	const float	strideWeights[]			= { 50, 10,  10,  10 };
	const int	instanceDivisors[]		= { 0,   1,   3, 129 };
	const float	instanceDivisorWeights[]= { 70, 30,  10,  10 };

	const int	indirectOffsets[]		= { 0,   1,   2 };
	const float indirectOffsetWeigths[]	= { 2,   1,   1 };
	const int	baseVertices[]			= { 0,   1,  -2,   4,  3 };
	const float baseVertexWeigths[]		= { 4,   1,   1,   1,  1 };

	gls::DrawTestSpec::Primitive primitives[] =
	{
		gls::DrawTestSpec::PRIMITIVE_POINTS,
		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
		gls::DrawTestSpec::PRIMITIVE_LINES,
		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
	};
	const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights;

	gls::DrawTestSpec::DrawMethod drawMethods[] =
	{
		gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT,
		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT,
	};
	const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights;

	gls::DrawTestSpec::IndexType indexTypes[] =
	{
		gls::DrawTestSpec::INDEXTYPE_BYTE,
		gls::DrawTestSpec::INDEXTYPE_SHORT,
		gls::DrawTestSpec::INDEXTYPE_INT,
	};
	const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights;

	gls::DrawTestSpec::InputType inputTypes[] =
	{
		gls::DrawTestSpec::INPUTTYPE_FLOAT,
		gls::DrawTestSpec::INPUTTYPE_FIXED,
		gls::DrawTestSpec::INPUTTYPE_BYTE,
		gls::DrawTestSpec::INPUTTYPE_SHORT,
		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE,
		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT,
		gls::DrawTestSpec::INPUTTYPE_INT,
		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT,
		gls::DrawTestSpec::INPUTTYPE_HALF,
		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10,
		gls::DrawTestSpec::INPUTTYPE_INT_2_10_10_10,
	};
	const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights;

	gls::DrawTestSpec::OutputType outputTypes[] =
	{
		gls::DrawTestSpec::OUTPUTTYPE_FLOAT,
		gls::DrawTestSpec::OUTPUTTYPE_VEC2,
		gls::DrawTestSpec::OUTPUTTYPE_VEC3,
		gls::DrawTestSpec::OUTPUTTYPE_VEC4,
		gls::DrawTestSpec::OUTPUTTYPE_INT,
		gls::DrawTestSpec::OUTPUTTYPE_UINT,
		gls::DrawTestSpec::OUTPUTTYPE_IVEC2,
		gls::DrawTestSpec::OUTPUTTYPE_IVEC3,
		gls::DrawTestSpec::OUTPUTTYPE_IVEC4,
		gls::DrawTestSpec::OUTPUTTYPE_UVEC2,
		gls::DrawTestSpec::OUTPUTTYPE_UVEC3,
		gls::DrawTestSpec::OUTPUTTYPE_UVEC4,
	};
	const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights;

	gls::DrawTestSpec::Usage usages[] =
	{
		gls::DrawTestSpec::USAGE_DYNAMIC_DRAW,
		gls::DrawTestSpec::USAGE_STATIC_DRAW,
		gls::DrawTestSpec::USAGE_STREAM_DRAW,
		gls::DrawTestSpec::USAGE_STREAM_READ,
		gls::DrawTestSpec::USAGE_STREAM_COPY,
		gls::DrawTestSpec::USAGE_STATIC_READ,
		gls::DrawTestSpec::USAGE_STATIC_COPY,
		gls::DrawTestSpec::USAGE_DYNAMIC_READ,
		gls::DrawTestSpec::USAGE_DYNAMIC_COPY,
	};
	const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights;

	std::set<deUint32>	insertedHashes;
	size_t				insertedCount = 0;

	for (int ndx = 0; ndx < numAttempts; ++ndx)
	{
		de::Random random(0xc551393 + ndx); // random does not depend on previous cases

		int					attributeCount = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights);
		int					drawCommandSize;
		gls::DrawTestSpec	spec;

		spec.apiType				= glu::ApiType::es(3,1);
		spec.primitive				= random.chooseWeighted<gls::DrawTestSpec::Primitive>	(DE_ARRAY_BEGIN(primitives),		DE_ARRAY_END(primitives),		primitiveWeights.weights);
		spec.primitiveCount			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(primitiveCounts),	DE_ARRAY_END(primitiveCounts),	primitiveCountWeights);
		spec.drawMethod				= random.chooseWeighted<gls::DrawTestSpec::DrawMethod>	(DE_ARRAY_BEGIN(drawMethods),		DE_ARRAY_END(drawMethods),		drawMethodWeights.weights);

		if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT)
			drawCommandSize = sizeof(deUint32[4]);
		else if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT)
			drawCommandSize = sizeof(deUint32[5]);
		else
		{
			DE_ASSERT(DE_FALSE);
			return;
		}

		spec.indexType				= random.chooseWeighted<gls::DrawTestSpec::IndexType>	(DE_ARRAY_BEGIN(indexTypes),		DE_ARRAY_END(indexTypes),		indexTypeWeights.weights);
		spec.indexPointerOffset		= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexOffsets),		DE_ARRAY_END(indexOffsets),		indexOffsetWeights);
		spec.indexStorage			= gls::DrawTestSpec::STORAGE_BUFFER;
		spec.first					= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(firsts),			DE_ARRAY_END(firsts),			firstWeights);
		spec.indexMin				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexMins),			DE_ARRAY_END(indexMins),		indexWeights);
		spec.indexMax				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexMaxs),			DE_ARRAY_END(indexMaxs),		indexWeights);
		spec.instanceCount			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(instanceCounts),	DE_ARRAY_END(instanceCounts),	instanceWeights);
		spec.indirectOffset			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indirectOffsets),	DE_ARRAY_END(indirectOffsets),	indirectOffsetWeigths) * drawCommandSize;
		spec.baseVertex				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(baseVertices),		DE_ARRAY_END(baseVertices),		baseVertexWeigths);

		// check spec is legal
		if (!spec.valid())
			continue;

		for (int attrNdx = 0; attrNdx < attributeCount;)
		{
			bool valid;
			gls::DrawTestSpec::AttributeSpec attribSpec;

			attribSpec.inputType			= random.chooseWeighted<gls::DrawTestSpec::InputType>	(DE_ARRAY_BEGIN(inputTypes),		DE_ARRAY_END(inputTypes),		inputTypeWeights.weights);
			attribSpec.outputType			= random.chooseWeighted<gls::DrawTestSpec::OutputType>	(DE_ARRAY_BEGIN(outputTypes),		DE_ARRAY_END(outputTypes),		outputTypeWeights.weights);
			attribSpec.storage				= gls::DrawTestSpec::STORAGE_BUFFER;
			attribSpec.usage				= random.chooseWeighted<gls::DrawTestSpec::Usage>		(DE_ARRAY_BEGIN(usages),			DE_ARRAY_END(usages),			usageWeights.weights);
			attribSpec.componentCount		= random.getInt(1, 4);
			attribSpec.offset				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), offsetWeights);
			attribSpec.stride				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(strides), DE_ARRAY_END(strides), strideWeights);
			attribSpec.normalize			= random.getBool();
			attribSpec.instanceDivisor		= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(instanceDivisors), DE_ARRAY_END(instanceDivisors), instanceDivisorWeights);
			attribSpec.useDefaultAttribute	= random.getBool();

			// check spec is legal
			valid = attribSpec.valid(spec.apiType);

			// we do not want interleaved elements. (Might result in some weird floating point values)
			if (attribSpec.stride && attribSpec.componentCount * gls::DrawTestSpec::inputTypeSize(attribSpec.inputType) > attribSpec.stride)
				valid = false;

			// try again if not valid
			if (valid)
			{
				spec.attribs.push_back(attribSpec);
				++attrNdx;
			}
		}

		// Do not collapse all vertex positions to a single positions
		if (spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
			spec.attribs[0].instanceDivisor = 0;

		// Is render result meaningful?
		{
			// Only one vertex
			if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
				continue;
			if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
				continue;

			// Triangle only on one axis
			if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLES || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP)
			{
				if (spec.attribs[0].componentCount == 1)
					continue;
				if (spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_FLOAT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_INT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_UINT)
					continue;
				if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
					continue;
			}
		}

		// Add case
		{
			deUint32 hash = spec.hash();
			for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
				hash = (hash << 2) ^ (deUint32)spec.attribs[attrNdx].hash();

			if (insertedHashes.find(hash) == insertedHashes.end())
			{
				// Only aligned cases
				if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET &&
					spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
					this->addChild(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), spec, de::toString(insertedCount).c_str(), spec.getDesc().c_str()));
				insertedHashes.insert(hash);

				++insertedCount;
			}
		}
	}
}

class BadCommandBufferCase : public TestCase
{
public:
	enum
	{
		CommandSize = 20
	};

					BadCommandBufferCase	(Context& context, const char* name, const char* desc, deUint32 alignment, deUint32 bufferSize, bool writeCommandToBuffer, deUint32 m_expectedError);
					~BadCommandBufferCase	(void);

	IterateResult	iterate					(void);

private:
	const deUint32	m_alignment;
	const deUint32	m_bufferSize;
	const bool		m_writeCommandToBuffer;
	const deUint32	m_expectedError;
};

BadCommandBufferCase::BadCommandBufferCase (Context& context, const char* name, const char* desc, deUint32 alignment, deUint32 bufferSize, bool writeCommandToBuffer, deUint32 expectedError)
	: TestCase					(context, name, desc)
	, m_alignment				(alignment)
	, m_bufferSize				(bufferSize)
	, m_writeCommandToBuffer	(writeCommandToBuffer)
	, m_expectedError			(expectedError)
{
}

BadCommandBufferCase::~BadCommandBufferCase (void)
{
}

BadCommandBufferCase::IterateResult	BadCommandBufferCase::iterate (void)
{
	const tcu::Vec4 vertexPositions[] =
	{
		tcu::Vec4(0,	0,		0, 1),
		tcu::Vec4(1,	0,		0, 1),
		tcu::Vec4(0,	1,		0, 1),
	};

	const deUint16 indices[] =
	{
		0, 2, 1,
	};

	DE_STATIC_ASSERT(CommandSize == sizeof(DrawElementsCommand));

	sglr::GLContext gl(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, 1, 1));

	deUint32 vaoID			= 0;
	deUint32 positionBuf	= 0;
	deUint32 indexBuf		= 0;
	deUint32 drawIndirectBuf= 0;
	deUint32 error;

	glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_commonVertexShaderSource) << glu::FragmentSource(s_commonFragmentShaderSource));
	deUint32			programID		= program.getProgram();
	deInt32				posLocation		= gl.getAttribLocation(programID, "a_position");

	DrawElementsCommand drawCommand;
	drawCommand.count				= 3;
	drawCommand.primCount			= 1;
	drawCommand.firstIndex			= 0;
	drawCommand.baseVertex			= 0;
	drawCommand.reservedMustBeZero	= 0;

	std::vector<deInt8> drawCommandBuffer;
	drawCommandBuffer.resize(m_bufferSize);

	deMemset(&drawCommandBuffer[0], 0, (int)drawCommandBuffer.size());

	if (m_writeCommandToBuffer)
	{
		DE_ASSERT(drawCommandBuffer.size() >= sizeof(drawCommand) + m_alignment);
		deMemcpy(&drawCommandBuffer[m_alignment], &drawCommand, sizeof(drawCommand));
	}

	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
	gl.genVertexArrays(1, &vaoID);
	gl.bindVertexArray(vaoID);

	gl.genBuffers(1, &positionBuf);
	gl.bindBuffer(GL_ARRAY_BUFFER, positionBuf);
	gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.vertexAttribDivisor(posLocation, 0);
	gl.enableVertexAttribArray(posLocation);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	gl.genBuffers(1, &indexBuf);
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	gl.genBuffers(1, &drawIndirectBuf);
	gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, drawIndirectBuf);
	gl.bufferData(GL_DRAW_INDIRECT_BUFFER, drawCommandBuffer.size(), &drawCommandBuffer[0], GL_STATIC_DRAW);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	gl.viewport(0, 0, 1, 1);

	gl.useProgram(programID);
	gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)(deUintptr)m_alignment);

	error = gl.getError();

	gl.useProgram(0);

	gl.deleteBuffers(1, &drawIndirectBuf);
	gl.deleteBuffers(1, &indexBuf);
	gl.deleteBuffers(1, &positionBuf);
	gl.deleteVertexArrays(1, &vaoID);

	m_testCtx.getLog() << tcu::TestLog::Message << "drawElementsIndirect generated " << glu::getErrorStr(error) << ", expecting " << glu::getErrorStr(m_expectedError) << "." << tcu::TestLog::EndMessage;

	if (error == m_expectedError)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tUnexpected error." << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
	}

	return STOP;
}

class BadAlignmentCase : public BadCommandBufferCase
{
public:
					BadAlignmentCase	(Context& context, const char* name, const char* desc, deUint32 alignment);
					~BadAlignmentCase	(void);
};

BadAlignmentCase::BadAlignmentCase (Context& context, const char* name, const char* desc, deUint32 alignment)
	: BadCommandBufferCase(context, name, desc, alignment, CommandSize+alignment, true, GL_INVALID_VALUE)
{
}

BadAlignmentCase::~BadAlignmentCase (void)
{
}

class BadBufferRangeCase : public BadCommandBufferCase
{
public:
					BadBufferRangeCase	(Context& context, const char* name, const char* desc, deUint32 offset);
					~BadBufferRangeCase	(void);
};

BadBufferRangeCase::BadBufferRangeCase (Context& context, const char* name, const char* desc, deUint32 offset)
	: BadCommandBufferCase(context, name, desc, offset, CommandSize, false, GL_INVALID_OPERATION)
{
}

BadBufferRangeCase::~BadBufferRangeCase (void)
{
}

class BadStateCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_CLIENT_BUFFER_VERTEXATTR = 0,
		CASE_CLIENT_BUFFER_COMMAND,
		CASE_DEFAULT_VAO,

		CASE_CLIENT_LAST
	};

						BadStateCase	(Context& context, const char* name, const char* desc, CaseType type);
						~BadStateCase	(void);

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

private:
	const CaseType		m_caseType;
};

BadStateCase::BadStateCase (Context& context, const char* name, const char* desc, CaseType type)
	: TestCase			(context, name, desc)
	, m_caseType		(type)
{
	DE_ASSERT(type < CASE_CLIENT_LAST);
}

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

void BadStateCase::init (void)
{
}

void BadStateCase::deinit (void)
{
}

BadStateCase::IterateResult BadStateCase::iterate (void)
{
	const tcu::Vec4 vertexPositions[] =
	{
		tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
	};

	const deUint16 indices[] =
	{
		0, 2, 1,
	};

	sglr::GLContext gl(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, 1, 1));

	deUint32			error;
	glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_commonVertexShaderSource) << glu::FragmentSource(s_commonFragmentShaderSource));
	deUint32			vaoID			= 0;
	deUint32			dataBufferID	= 0;
	deUint32			indexBufferID	= 0;
	deUint32			cmdBufferID		= 0;

	const deUint32		programID		= program.getProgram();
	const deInt32		posLocation		= gl.getAttribLocation(programID, "a_position");

	DrawElementsCommand drawCommand;
	drawCommand.count				= 3;
	drawCommand.primCount			= 1;
	drawCommand.firstIndex			= 0;
	drawCommand.baseVertex			= 0;
	drawCommand.reservedMustBeZero	= 0;

	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	if (m_caseType == CASE_CLIENT_BUFFER_VERTEXATTR)
	{
		// \note We use default VAO since we use client pointers. Trying indirect draw with default VAO is also an error. => This test does two illegal operations

		gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, vertexPositions);
		gl.enableVertexAttribArray(posLocation);
		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
	}
	else if (m_caseType == CASE_CLIENT_BUFFER_COMMAND)
	{
		gl.genVertexArrays(1, &vaoID);
		gl.bindVertexArray(vaoID);

		gl.genBuffers(1, &dataBufferID);
		gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
		gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
		gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
		gl.enableVertexAttribArray(posLocation);
		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
	}
	else if (m_caseType == CASE_DEFAULT_VAO)
	{
		gl.genBuffers(1, &dataBufferID);
		gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
		gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
		gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
		gl.enableVertexAttribArray(posLocation);
		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
	}
	else
		DE_ASSERT(DE_FALSE);

	gl.genBuffers(1, &indexBufferID);
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	if (m_caseType != CASE_CLIENT_BUFFER_COMMAND)
	{
		gl.genBuffers(1, &cmdBufferID);
		gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBufferID);
		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
	}

	gl.viewport(0, 0, 1, 1);

	gl.useProgram(programID);
	gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (m_caseType != CASE_CLIENT_BUFFER_COMMAND) ? (DE_NULL) : (&drawCommand));

	error = gl.getError();

	gl.bindVertexArray(0);
	gl.useProgram(0);

	if (error == GL_INVALID_OPERATION)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected error. Expected GL_INVALID_OPERATION, got " << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
	}

	return STOP;
}

class BadDrawModeCase : public TestCase
{
public:
	enum DrawType
	{
		DRAW_ARRAYS = 0,
		DRAW_ELEMENTS,
		DRAW_ELEMENTS_BAD_INDEX,

		DRAW_LAST
	};

						BadDrawModeCase	(Context& context, const char* name, const char* desc, DrawType type);
						~BadDrawModeCase(void);

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

private:
	const DrawType		m_drawType;
};

BadDrawModeCase::BadDrawModeCase (Context& context, const char* name, const char* desc, DrawType type)
	: TestCase			(context, name, desc)
	, m_drawType		(type)
{
	DE_ASSERT(type < DRAW_LAST);
}

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

void BadDrawModeCase::init (void)
{
}

void BadDrawModeCase::deinit (void)
{
}

BadDrawModeCase::IterateResult BadDrawModeCase::iterate (void)
{
	const tcu::Vec4 vertexPositions[] =
	{
		tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
	};

	const deUint16 indices[] =
	{
		0, 2, 1,
	};

	sglr::GLContext		gl				(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, 1, 1));

	deUint32			error;
	glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_commonVertexShaderSource) << glu::FragmentSource(s_commonFragmentShaderSource));
	deUint32			vaoID			= 0;
	deUint32			dataBufferID	= 0;
	deUint32			indexBufferID	= 0;
	deUint32			cmdBufferID		= 0;

	const deUint32		programID		= program.getProgram();
	const deInt32		posLocation		= gl.getAttribLocation(programID, "a_position");
	const glw::GLenum	mode			= (m_drawType == DRAW_ELEMENTS_BAD_INDEX) ? (GL_TRIANGLES) : (0x123);
	const glw::GLenum	indexType		= (m_drawType == DRAW_ELEMENTS_BAD_INDEX) ? (0x123) : (GL_UNSIGNED_SHORT);

	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	// vao

	gl.genVertexArrays(1, &vaoID);
	gl.bindVertexArray(vaoID);

	// va

	gl.genBuffers(1, &dataBufferID);
	gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
	gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray(posLocation);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	// index

	if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
	{
		gl.genBuffers(1, &indexBufferID);
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
	}

	// cmd

	gl.genBuffers(1, &cmdBufferID);
	gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBufferID);
	if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
	{
		DrawElementsCommand drawCommand;
		drawCommand.count				= 3;
		drawCommand.primCount			= 1;
		drawCommand.firstIndex			= 0;
		drawCommand.baseVertex			= 0;
		drawCommand.reservedMustBeZero	= 0;

		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
	}
	else if (m_drawType == DRAW_ARRAYS)
	{
		DrawArraysCommand drawCommand;
		drawCommand.count				= 3;
		drawCommand.primCount			= 1;
		drawCommand.first				= 0;
		drawCommand.reservedMustBeZero	= 0;

		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
	}
	else
		DE_ASSERT(DE_FALSE);
	glu::checkError(gl.getError(), "", __FILE__, __LINE__);

	gl.viewport(0, 0, 1, 1);
	gl.useProgram(programID);
	if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
		gl.drawElementsIndirect(mode, indexType, DE_NULL);
	else if (m_drawType == DRAW_ARRAYS)
		gl.drawArraysIndirect(mode, DE_NULL);
	else
		DE_ASSERT(DE_FALSE);

	error = gl.getError();
	gl.useProgram(0);

	if (error == GL_INVALID_ENUM)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected error. Expected GL_INVALID_ENUM, got " << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
	}

	return STOP;
}

class NegativeGroup : public TestCaseGroup
{
public:
			NegativeGroup	(Context& context, const char* name, const char* descr);
			~NegativeGroup	(void);

	void	init			(void);
};

NegativeGroup::NegativeGroup (Context& context, const char* name, const char* descr)
	: TestCaseGroup	(context, name, descr)
{
}

NegativeGroup::~NegativeGroup (void)
{
}

void NegativeGroup::init (void)
{
	// invalid alignment
	addChild(new BadAlignmentCase	(m_context, "command_bad_alignment_1",								"Bad command alignment",					1));
	addChild(new BadAlignmentCase	(m_context, "command_bad_alignment_2",								"Bad command alignment",					2));
	addChild(new BadAlignmentCase	(m_context, "command_bad_alignment_3",								"Bad command alignment",					3));

	// command only partially or not at all in the buffer
	addChild(new BadBufferRangeCase	(m_context, "command_offset_partially_in_buffer",					"Command not fully in the buffer range",	BadBufferRangeCase::CommandSize - 16));
	addChild(new BadBufferRangeCase	(m_context, "command_offset_not_in_buffer",							"Command not in the buffer range",			BadBufferRangeCase::CommandSize));
	addChild(new BadBufferRangeCase	(m_context, "command_offset_not_in_buffer_unsigned32_wrap",			"Command not in the buffer range",			0xFFFFFFFC));
	addChild(new BadBufferRangeCase	(m_context, "command_offset_not_in_buffer_signed32_wrap",			"Command not in the buffer range",			0x7FFFFFFC));

	// use with client data and default vao
	addChild(new BadStateCase		(m_context, "client_vertex_attrib_array",							"Vertex attrib array in the client memory",	BadStateCase::CASE_CLIENT_BUFFER_VERTEXATTR));
	addChild(new BadStateCase		(m_context, "client_command_array",									"Command array in the client memory",		BadStateCase::CASE_CLIENT_BUFFER_COMMAND));
	addChild(new BadStateCase		(m_context, "default_vao",											"Use with default vao",						BadStateCase::CASE_DEFAULT_VAO));

	// invalid mode & type
	addChild(new BadDrawModeCase	(m_context, "invalid_mode_draw_arrays",								"Call DrawArraysIndirect with bad mode",	BadDrawModeCase::DRAW_ARRAYS));
	addChild(new BadDrawModeCase	(m_context, "invalid_mode_draw_elements",							"Call DrawelementsIndirect with bad mode",	BadDrawModeCase::DRAW_ELEMENTS));
	addChild(new BadDrawModeCase	(m_context, "invalid_type_draw_elements",							"Call DrawelementsIndirect with bad type",	BadDrawModeCase::DRAW_ELEMENTS_BAD_INDEX));
}

} // anonymous

DrawTests::DrawTests (Context& context)
	: TestCaseGroup(context, "draw_indirect", "Indirect drawing tests")
{
}

DrawTests::~DrawTests (void)
{
}

void DrawTests::init (void)
{
	// Basic
	{
		const gls::DrawTestSpec::DrawMethod basicMethods[] =
		{
			gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT,
			gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT,
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
		{
			const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
			const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);

			this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
		}
	}

	// extreme instancing

	this->addChild(new InstancingGroup(m_context, "instancing", "draw tests with a large instance count."));

	// compute shader generated commands

	this->addChild(new ComputeShaderGeneratedGroup(m_context, "compute_interop", "draw tests with a draw command generated in compute shader."));

	// Random

	this->addChild(new RandomGroup(m_context, "random", "random draw commands."));

	// negative

	this->addChild(new NegativeGroup(m_context, "negative", "invalid draw commands with defined error codes."));
}

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