/*-------------------------------------------------------------------------
 * 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       posXp1      = (float(x+1u) / float(gridSize)) * 2.0 - 1.0;\n"
				<< "        float       posY        = (float(y)    / float(gridSize)) * 2.0 - 1.0;\n"
				<< "        float       posYp1      = (float(y+1u) / float(gridSize)) * 2.0 - 1.0;\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(posXp1, posY,   0.0, 1.0);\n"
				<< "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 0u] = vec4(posXp1, posYp1, 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(posXp1, posYp1, 0.0, 1.0);\n"
				<< "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 0u] = vec4(posX,   posYp1, 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), glu::BufferOffsetAsPointer(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 = glu::BufferOffsetAsPointer(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
