/*-------------------------------------------------------------------------
 * 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, glu::ContextType contextType, gls::DrawTestSpec::DrawMethod method)
{
	spec.apiType							= glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
	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.");
		glu::ContextType	contextType			= m_context.getRenderContext().getType();
		gls::DrawTestSpec	spec;

		spec.apiType							= glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
		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.");
		glu::ContextType	contextType			= m_context.getRenderContext().getType();
		gls::DrawTestSpec	spec;

		spec.apiType							= glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
		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.");
		glu::ContextType	contextType				= m_context.getRenderContext().getType();
		gls::DrawTestSpec	spec;

		spec.apiType								= glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
		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*.");
		glu::ContextType	contextType			= m_context.getRenderContext().getType();
		gls::DrawTestSpec	spec;

		spec.apiType							= glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
		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_context.getRenderContext().getType(), 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_context.getRenderContext().getType(), 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_context.getRenderContext().getType(), 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;
	glu::ContextType	contextType = m_context.getRenderContext().getType();
	glu::ApiType		apiType = glu::isContextTypeES(contextType) ? glu::ApiType::es(3,1) : contextType.getAPI();

	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				= apiType;
		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)
{
	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		if (m_caseType == CASE_CLIENT_BUFFER_VERTEXATTR)
			throw tcu::NotSupportedError("The negative test for vertex attrib array in the client memory is not supported in the GL context");
		if (m_caseType == CASE_DEFAULT_VAO)
			throw tcu::NotSupportedError("The negative test for use with default vao is not supported in the GL context");
	}

}

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
