/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * 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
 */ /*-------------------------------------------------------------------*/

#include "es31cDrawIndirectTests.hpp"
#include "gluContextInfo.hpp"
#include "glwEnums.hpp"
#include "tcuMatrix.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuVectorUtil.hpp"

#include <map>

namespace glcts
{
using namespace glw;
namespace
{

class DILogger
{
public:
	DILogger() : null_log_(0)
	{
	}

	DILogger(const DILogger& rhs)
	{
		null_log_ = rhs.null_log_;
		if (!null_log_)
		{
			str_ << rhs.str_.str();
		}
	}

	~DILogger()
	{
		s_tcuLog->writeMessage(str_.str().c_str());
		if (!str_.str().empty())
		{
			s_tcuLog->writeMessage(NL);
		}
	}

	template <class T>
	DILogger& operator<<(const T& t)
	{
		if (!null_log_)
		{
			str_ << t;
		}
		return *this;
	}

	DILogger& nullify()
	{
		null_log_ = true;
		return *this;
	}

	static void setOutput(tcu::TestLog& log)
	{
		s_tcuLog = &log;
	}

private:
	void				 operator=(const DILogger&);
	bool				 null_log_;
	std::ostringstream   str_;
	static tcu::TestLog* s_tcuLog;
};
tcu::TestLog* DILogger::s_tcuLog = NULL;

class DIResult
{
public:
	DIResult() : status_(NO_ERROR)
	{
	}

	DILogger error()
	{
		return sub_result(ERROR);
	}
	long code() const
	{
		return status_;
	}
	DILogger sub_result(long _code)
	{
		if (_code == NO_ERROR)
		{
			return sub_result_inner(_code).nullify();
		}
		else
		{
			return sub_result_inner(_code);
		}
	}

private:
	DILogger sub_result_inner(long _code)
	{
		status_ |= _code;
		return DILogger();
	}
	DILogger logger_;
	long	 status_;
};

namespace test_api
{
struct ES3
{
	static bool isES()
	{
		return true;
	}
	static std::string glslVer(bool = false)
	{
		return "#version 310 es";
	}
	static void ES_Only()
	{
	}
};

struct GL
{
	static bool isES()
	{
		return false;
	}
	static std::string glslVer(bool compute = false)
	{
		if (compute)
		{
			return "#version 430";
		}
		else
		{
			return "#version 400";
		}
	}
	static void GL_Only()
	{
	}
};
}

namespace shaders
{

template <typename api>
std::string vshSimple()
{
	return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL "    gl_Position = i_vertex;" NL "}";
}
template <typename api>
std::string vshSimple_point()
{
	return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL "    gl_Position = i_vertex;" NL
							   "#if defined(GL_ES)" NL "    gl_PointSize = 1.0;" NL "#endif" NL "}";
}

template <typename api>
std::string fshSimple()
{
	return api::glslVer() + NL "precision highp float; " NL "out vec4 outColor;" NL "void main() {" NL
							   "  outColor = vec4(0.1,0.2,0.3,1.0);" NL "}";
}
}

class DrawIndirectBase : public glcts::SubcaseBase
{
protected:
	typedef std::vector<unsigned int> CDataArray;
	typedef std::vector<tcu::Vec3>	CVertexArray;
	typedef std::vector<tcu::Vec4>	CColorArray;
	typedef std::vector<GLuint>		  CElementArray;

	enum TDrawFunction
	{
		DRAW_ARRAYS,
		DRAW_ELEMENTS,
	};

	typedef struct
	{
		GLuint count;
		GLuint primCount;
		GLuint first;
		GLuint reservedMustBeZero;
	} DrawArraysIndirectCommand;

	typedef struct
	{
		GLuint count;
		GLuint primCount;
		GLuint firstIndex;
		GLint  baseVertex;
		GLuint reservedMustBeZero;
	} DrawElementsIndirectCommand;

	int getWindowWidth()
	{
		return m_context.getRenderContext().getRenderTarget().getWidth();
	}

	int getWindowHeight()
	{
		return m_context.getRenderContext().getRenderTarget().getHeight();
	}

	void getDataSize(int& width, int& height)
	{
		width  = std::min(getWindowWidth(), 16384);				 // Cap width to 16384
		height = std::min(getWindowHeight(), 4 * 16384 / width); // Height is 4 if width is capped
	}

	GLuint CreateComputeProgram(const std::string& cs, bool linkAndCheck)
	{
		const GLuint p = glCreateProgram();

		const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
		glAttachShader(p, sh);
		glDeleteShader(sh);
		const char* const src[1] = { cs.c_str() };
		glShaderSource(sh, 1, src, NULL);
		glCompileShader(sh);

		if (linkAndCheck)
		{
			glLinkProgram(p);
			if (!CheckProgram(p))
			{
				return 0;
			}
		}

		return p;
	}

	GLuint CreateProgram(const std::string& vs, const std::string& gs, const std::string& fs, bool linkAndCheck)
	{
		const GLuint p = glCreateProgram();

		if (!vs.empty())
		{
			const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
			glAttachShader(p, sh);
			glDeleteShader(sh);
			const char* const src[1] = { vs.c_str() };
			glShaderSource(sh, 1, src, NULL);
			glCompileShader(sh);
		}
		if (!gs.empty())
		{
			const GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
			glAttachShader(p, sh);
			glDeleteShader(sh);
			const char* const src[1] = { gs.c_str() };
			glShaderSource(sh, 1, src, NULL);
			glCompileShader(sh);
		}
		if (!fs.empty())
		{
			const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
			glAttachShader(p, sh);
			glDeleteShader(sh);
			const char* const src[1] = { fs.c_str() };
			glShaderSource(sh, 1, src, NULL);
			glCompileShader(sh);
		}

		if (linkAndCheck)
		{
			glLinkProgram(p);
			if (!CheckProgram(p))
			{
				return 0;
			}
		}

		return p;
	}

	long CheckProgram(GLuint program)
	{
		DIResult status;
		GLint	progStatus;
		glGetProgramiv(program, GL_LINK_STATUS, &progStatus);

		if (progStatus == GL_FALSE)
		{

			status.error() << "GL_LINK_STATUS is false";

			GLint attached_shaders;
			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);

			if (attached_shaders > 0)
			{
				std::vector<GLuint> shaders(attached_shaders);
				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);

				for (GLint i = 0; i < attached_shaders; ++i)
				{
					// shader type
					GLenum type;
					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
					switch (type)
					{
					case GL_VERTEX_SHADER:
						status.error() << "*** Vertex Shader ***\n";
						break;
					case GL_FRAGMENT_SHADER:
						status.error() << "*** Fragment Shader ***\n";
						break;
					case GL_COMPUTE_SHADER:
						status.error() << "*** Compute Shader ***\n";
						break;
					default:
						status.error() << "*** Unknown Shader ***\n";
						break;
					}

					// shader source
					GLint length;
					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
					if (length > 0)
					{
						std::vector<GLchar> source(length);
						glGetShaderSource(shaders[i], length, NULL, &source[0]);
						status.error() << source[0];
					}

					// shader info log
					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
					if (length > 0)
					{
						std::vector<GLchar> log(length);
						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
						status.error() << &log[0];
					}
				}
			}

			// program info log
			GLint length;
			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
			if (length > 0)
			{
				std::vector<GLchar> log(length);
				glGetProgramInfoLog(program, length, NULL, &log[0]);
				status.error() << &log[0];
			}
		}

		return status.code() == NO_ERROR;
	}

	template <typename api>
	void ReadPixelsFloat(int x, int y, int width, int height, void* data);

	template <typename api>
	void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data);

	template <typename T>
	void DataGen(std::vector<T>& data, unsigned int sizeX, unsigned int sizeY, T valueMin, T valueMax)
	{
		data.resize(sizeX * sizeY, 0);
		T range = valueMax - valueMin;
		T stepX = range / sizeX;
		T stepY = range / sizeY;

		for (unsigned int i = 0; i < sizeY; ++i)
		{
			T valueY = i * stepY;

			for (unsigned int j = 0; j < sizeX; ++j)
			{
				data[j + i * sizeX] = valueMin + j * stepX + valueY;
			}
		}
	}

	template <typename T>
	long DataCompare(const std::vector<T>& dataRef, unsigned int widthRef, unsigned int heightRef,
					 const std::vector<T>& dataTest, unsigned int widthTest, unsigned int heightTest,
					 unsigned offsetYRef = 0, unsigned offsetYTest = 0)
	{
		if (widthRef * heightRef > dataRef.size())
			throw std::runtime_error("Invalid reference buffer resolution!");

		if (widthTest * heightTest > dataTest.size())
			throw std::runtime_error("Invalid test buffer resolution!");

		unsigned int width  = std::min(widthRef, widthTest);
		unsigned int height = std::min(heightRef, heightTest);

		for (unsigned int i = 0; i < height; ++i)
		{
			unsigned int offsetRef  = (i + offsetYRef) * widthRef;
			unsigned int offsetTest = (i + offsetYTest) * widthTest;

			for (size_t j = 0; j < width; ++j)
			{
				if (dataRef[offsetRef + j] != dataTest[offsetTest + j])
				{
					DIResult status;
					status.error() << "Compare failed: different values [x: " << j << ", y: " << i + offsetYTest
								   << ", reference: " << dataRef[offsetRef + j]
								   << ", test: " << dataTest[offsetTest + j] << "]";
					return status.code();
				}
			}
		}

		return NO_ERROR;
	}

	template <typename api>
	long BindingPointCheck(GLuint expectedValue)
	{
		DIResult status;

		GLint valueInt = -9999;
		glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueInt);
		if (valueInt != static_cast<GLint>(expectedValue))
		{
			status.error() << "glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueInt
						   << ", expected: " << expectedValue;
		}

		GLboolean valueBool = expectedValue ? GL_FALSE : GL_TRUE;
		glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueBool);
		if (valueBool != (expectedValue ? GL_TRUE : GL_FALSE))
		{
			status.error() << "glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: "
						   << BoolToString(valueBool)
						   << ", expected: " << BoolToString(expectedValue ? GL_TRUE : GL_FALSE);
		}

		GLfloat valueFloat		   = -9999;
		GLfloat expectedFloatValue = static_cast<GLfloat>(expectedValue);
		glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueFloat);
		if (valueFloat != expectedFloatValue)
		{
			status.error() << "glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueFloat
						   << ", expected: " << expectedValue;
		}

		if (!api::isES())
		{
			GLdouble valueDouble = -9999;
			glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueDouble);
			if (valueDouble != static_cast<GLdouble>(expectedValue))
			{
				status.error() << "glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: "
							   << valueDouble << ", expected: " << expectedValue;
			}
		}

		return status.code();
	}

	template <typename T>
	long BuffersCompare(const std::vector<T>& bufferTest, unsigned int widthTest, unsigned int heightTest,
						const std::vector<T>& bufferRef, unsigned int widthRef, unsigned int heightRef)
	{

		const tcu::PixelFormat& pixelFormat = m_context.getRenderContext().getRenderTarget().getPixelFormat();
		tcu::Vec4				epsilon		= tcu::Vec4(
			1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
			1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));

		double stepX = widthRef / static_cast<double>(widthTest);
		double stepY = heightRef / static_cast<double>(heightTest);
		for (unsigned int i = 0; i < heightTest; ++i)
		{
			unsigned int offsetTest = i * widthTest;
			unsigned int offsetRef  = static_cast<int>(i * stepY + 0.5) * widthRef;
			for (unsigned int j = 0; j < widthTest; ++j)
			{
				unsigned int posXRef = static_cast<int>(j * stepX + 0.5);
				if (!ColorVerify(bufferTest[j + offsetTest], bufferRef[posXRef + offsetRef], epsilon))
				{
					DIResult status;
					status.error() << "(x,y)= (" << j << "," << i << "). Color RGBA(" << bufferTest[j + offsetTest][0]
								   << "," << bufferTest[j + offsetTest][1] << "," << bufferTest[j + offsetTest][2]
								   << "," << bufferTest[j + offsetTest][3] << ") is different than expected RGBA("
								   << bufferRef[posXRef + offsetRef][0] << "," << bufferRef[posXRef + offsetRef][1]
								   << "," << bufferRef[posXRef + offsetRef][2] << ","
								   << bufferRef[posXRef + offsetRef][3] << ")";
					return status.code();
				}
			}
		}
		return NO_ERROR;
	}

	template <typename T>
	bool ColorVerify(T color, T colorExpected, tcu::Vec4 epsilon)
	{
		for (int i = 0; i < 3; ++i)
		{
			if (fabsf(colorExpected[i] - color[i]) > epsilon[i])
				return false;
		}
		return true;
	}

	long BufferCheck(const CDataArray& dataRef, unsigned int widthRef, unsigned int heightRef, const void* bufTest,
					 unsigned int widthTest, unsigned int heightTest, unsigned int offsetYRef = 0,
					 unsigned int offsetYTest = 0)
	{
		if (bufTest == 0)
		{
			throw std::runtime_error("Invalid test buffer!");
		}

		CDataArray dataTest(widthTest * heightTest, 0);
		memcpy(&dataTest[0], bufTest, widthTest * heightTest * sizeof(unsigned int));

		return DataCompare(dataRef, widthRef, heightRef, dataTest, widthTest, heightTest, offsetYRef, offsetYTest);
	}

	template <typename api>
	long StateValidate(GLboolean mapped, GLbitfield access, GLbitfield accessFlag, GLintptr offset, GLsizeiptr length)
	{
		DIResult result;

		if (!api::isES())
		{
			int v;
			glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS, &v);
			if (v != static_cast<int>(access))
			{
				result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS) returned incorrect state: "
							   << AccessToString(v) << ", expected: " << AccessToString(access);
			}
		}

		int v;
		glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS_FLAGS, &v);
		if (v != static_cast<int>(accessFlag))
		{
			result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS) returned incorrect state: " << v
						   << ", expected: " << accessFlag;
		}

		glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAPPED, &v);
		if (v != mapped)
		{
			result.error() << "glGetBufferParameteriv(GL_BUFFER_MAPPED) returned incorrect state: "
						   << BoolToString((GLboolean)v) << ", expected: " << BoolToString((GLboolean)access);
		}

		glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_OFFSET, &v);
		if (v != offset)
		{
			result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_OFFSET) returned incorrect offset: " << v
						   << ", expected: " << offset;
		}

		glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_LENGTH, &v);
		if (v != length)
		{
			result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_LENGTH) returned incorrect length: " << v
						   << ", expected: " << length;
		}

		return result.code();
	}

	void PointsGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output)
	{
		output.reserve(drawSizeY * 2);
		float rasterSizeX = 2.0f / static_cast<float>(getWindowWidth());
		float rasterSizeY = 2.0f / static_cast<float>(getWindowHeight());
		for (unsigned int i = 0; i < drawSizeY; ++i)
		{
			float offsetY = -1.0f + rasterSizeY * static_cast<float>(i) + rasterSizeY / 2;
			for (unsigned int j = 0; j < drawSizeX; ++j)
			{
				float offsetX = -1.0f + rasterSizeX * static_cast<float>(j) + rasterSizeX / 2;
				output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
			}
		}
	}

	float LinesOffsetY(unsigned int i, float rasterSize)
	{
		// Offset lines slightly from the center of pixels so as not to hit rasterizer
		// tie-break conditions (the right-edge of the screen at half-integer pixel
		// heights is the right corner of a diamond). rasterSize/16 is the smallest
		// offset that the spec guarantees the rasterizer can resolve.
		return -1.0f + rasterSize * static_cast<float>(i) + rasterSize / 2 + rasterSize / 16;
	}

	void LinesGen(unsigned int, unsigned int drawSizeY, CColorArray& output)
	{
		output.reserve(drawSizeY * 2);
		float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
		for (unsigned int i = 0; i < drawSizeY; ++i)
		{
			float offsetY = LinesOffsetY(i, rasterSize);
			output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
		}
	}

	void LinesAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray& output)
	{
		float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
		for (unsigned int i = 0; i < drawSizeY; ++i)
		{
			float offsetY = LinesOffsetY(i, rasterSize);
			output.push_back(tcu::Vec4(-1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj
			output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj
		}
	}

	void LineStripAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray& output)
	{
		float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
		output.push_back(tcu::Vec4(-1.5f, rasterSize / 2, 0.0f, 1.0f));
		for (unsigned int i = 0; i < drawSizeY; ++i)
		{
			float offsetY = LinesOffsetY(i, rasterSize);
			output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
		}
		output.push_back(tcu::Vec4(1.5f, 1.0f - rasterSize / 2, 0.0f, 1.0f));
	}

	void TrianglesGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output)
	{
		output.reserve(drawSizeX * 2 * 6);

		switch (drawSizeX)
		{
		case 1:
		{
			output.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(4.0f, -1.0f, 0.0f, 1.0f));
			output.push_back(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f));
		}
		break;
		case 0:
		{
			throw std::runtime_error("Invalid drawSizeX!");
		}
		break;
		default:
		{
			float drawStepX = 2.0f / static_cast<float>(drawSizeX);
			float drawStepY = 2.0f / static_cast<float>(drawSizeY);

			for (unsigned int i = 0; i < drawSizeY; ++i)
			{
				float offsetY = -1.0f + drawStepY * static_cast<float>(i);
				for (unsigned int j = 0; j < drawSizeX; ++j)
				{
					float offsetX = -1.0f + drawStepX * static_cast<float>(j);

					output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
					output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f));
					output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f));

					output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f));
					output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY + drawStepY, 0.0f, 1.0f));
					output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f));
				}
			}
		}
		break;
		}
	}

	void TrianglesAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output)
	{
		// Add a small amount (quarter pixel) of jitter to add to the rectangle sides to avoid
		// triangle edges landing precisely on fragment centers.
		float jigX = 0.5f / getWindowWidth();
		float jigY = 0.5f / getWindowHeight();

		float sizeX = 1.0f / static_cast<float>(drawSizeX);
		float sizeY = 1.0f / static_cast<float>(drawSizeY);

		for (unsigned int i = 0; i < drawSizeX; ++i)
		{
			float offsetY = -0.5f + jigY + sizeY * static_cast<float>(i);
			for (unsigned int j = 0; j < drawSizeY; ++j)
			{
				float offsetX = -0.5f + jigX + sizeX * static_cast<float>(j);

				output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f));

				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f));
			}
		}
	}

	void TriangleStripAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output)
	{
		// Add a small amount (quarter pixel) of jitter to add to the rectangle sides to avoid
		// triangle edges landing precisely on fragment centers.
		float jigX = 0.5f / getWindowWidth();
		float jigY = 0.5f / getWindowHeight();

		float sizeX = 1.0f / static_cast<float>(drawSizeX);
		float sizeY = 1.0f / static_cast<float>(drawSizeY);

		for (unsigned int i = 0; i < drawSizeX; ++i)
		{
			float offsetY = -0.5f + jigY + sizeY * static_cast<float>(i);
			for (unsigned int j = 0; j < drawSizeY; ++j)
			{
				float offsetX = -0.5f + jigX + sizeX * static_cast<float>(j);

				output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
				output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY - sizeY, 0.0f, 1.0f));
			}
		}
	}

	void PrimitiveGen(GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output)
	{
		switch (primitiveType)
		{
		case GL_POINTS:
			PointsGen(drawSizeX, drawSizeY, output);
			break;
		case GL_LINES:
		case GL_LINE_STRIP:
		case GL_LINE_LOOP:
			LinesGen(drawSizeX, drawSizeY, output);
			break;
		case GL_LINES_ADJACENCY:
			LinesAdjacencyGen(drawSizeX, drawSizeY, output);
			break;
		case GL_LINE_STRIP_ADJACENCY:
			LineStripAdjacencyGen(drawSizeX, drawSizeY, output);
			break;
		case GL_TRIANGLES:
		case GL_TRIANGLE_STRIP:
		case GL_TRIANGLE_FAN:
			TrianglesGen(drawSizeX, drawSizeY, output);
			break;
		case GL_TRIANGLES_ADJACENCY:
			TrianglesAdjacencyGen(drawSizeX, drawSizeY, output);
			break;
		case GL_TRIANGLE_STRIP_ADJACENCY:
			TriangleStripAdjacencyGen(drawSizeX, drawSizeY, output);
			break;
		default:
			throw std::runtime_error("Unknown primitive type!");
			break;
		}
	}

	std::string BoolToString(GLboolean value)
	{
		if (value == GL_TRUE)
			return "GL_TRUE";

		return "GL_FALSE";
	}

	std::string AccessToString(GLbitfield access)
	{
		switch (access)
		{
		case GL_READ_WRITE:
			return "GL_READ_WRITE";
			break;
		case GL_READ_ONLY:
			return "GL_READ_ONLY";
			break;
		case GL_WRITE_ONLY:
			return "GL_WRITE_ONLY";
			break;
		default:
			throw std::runtime_error("Invalid access type!");
			break;
		}
	}
};

template <>
void DrawIndirectBase::ReadPixelsFloat<test_api::GL>(int x, int y, int width, int height, void* data)
{
	glReadPixels(x, y, width, height, GL_RGBA, GL_FLOAT, data);
}

template <>
void DrawIndirectBase::ReadPixelsFloat<test_api::ES3>(int x, int y, int width, int height, void* data)
{
	// Use 1010102 pixel buffer for RGB10_A2 FBO to preserve precision during pixel transfer
	std::vector<GLuint>     uData(width * height);
	const tcu::PixelFormat& pixelFormat = m_context.getRenderContext().getRenderTarget().getPixelFormat();
	GLfloat*                fData       = reinterpret_cast<GLfloat*>(data);
	GLenum                  type        = ((pixelFormat.redBits   == 10) &&
	                                       (pixelFormat.greenBits == 10) &&
	                                       (pixelFormat.blueBits  == 10) &&
	                                       (pixelFormat.alphaBits == 2)) ?
	                                      GL_UNSIGNED_INT_2_10_10_10_REV :
	                                      GL_UNSIGNED_BYTE;

	glReadPixels(x, y, width, height, GL_RGBA, type, &uData[0]);

	if (type == GL_UNSIGNED_BYTE)
	{
		for (size_t i = 0; i < uData.size(); i++)
		{
			GLubyte* uCompData = reinterpret_cast<GLubyte*>(&uData[i]);

			for (size_t c = 0; c < 4; c++)
			{
				fData[i * 4 + c] = float(uCompData[c]) / 255.0f;
			}
		}
	}
	else
	{
		for (size_t i = 0; i < uData.size(); i++)
		{
			fData[i * 4]     = float(uData[i] & 0x3FF) / 1023.0f;
			fData[i * 4 + 1] = float((uData[i] >> 10) & 0x3FF) / 1023.0f;
			fData[i * 4 + 2] = float((uData[i] >> 20) & 0x3FF) / 1023.0f;
			fData[i * 4 + 3] = float((uData[i] >> 30) & 0x3) / 3.0f;
		}
	}
}

template <>
void DrawIndirectBase::GetBufferSubData<test_api::GL>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data)
{
	glGetBufferSubData(target, offset, size, data);
}

template <>
void DrawIndirectBase::GetBufferSubData<test_api::ES3>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data)
{
	void* ptr = glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
	memcpy(data, ptr, size);
	glUnmapBuffer(target);
}

template <typename api>
struct CDefaultBindingPoint : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Draw Indirect: Check default binding point";
	}

	virtual std::string Purpose()
	{
		return "Verify that default binding point is set to zero";
	}

	virtual std::string Method()
	{
		return "Use glGetIntegerv, glGetBooleanv, glGetFloatv, glGetDoublev to get default binding point";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if default binding point is zero";
	}

	virtual long Run()
	{
		return BindingPointCheck<api>(0);
	}
};

template <typename api>
struct CZeroBindingPoint : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Draw Indirect: Zero binding point";
	}

	virtual std::string Purpose()
	{
		return "Verify that binding point is set to zero";
	}

	virtual std::string Method()
	{
		return "Bind zero and check that binding point is set to zero";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if binding point is set to zero";
	}

	virtual long Run()
	{
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);

		return BindingPointCheck<api>(0);
	}
};

template <typename api>
struct CSingleBindingPoint : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Draw Indirect: Single binding point";
	}

	virtual std::string Purpose()
	{
		return "Verify that binding point is set to correct value";
	}

	virtual std::string Method()
	{
		return "Bind non-zero buffer and check that binding point is set to correct value";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if binding point is set to correct value";
	}

	virtual long Run()
	{
		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

		long ret = BindingPointCheck<api>(_buffer);

		return ret;
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(1, &_buffer);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <typename api>
class CMultiBindingPoint : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Draw Indirect: Multi binding point";
	}

	virtual std::string Purpose()
	{
		return "Verify that binding points are set to correct value";
	}

	virtual std::string Method()
	{
		return "Bind in loop non-zero buffers and check that binding points are set to correct value";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if binding points are set to correct value";
	}

	virtual long Run()
	{
		DIResult result;

		const int buffNum = sizeof(_buffers) / sizeof(_buffers[0]);

		glGenBuffers(buffNum, _buffers);

		for (int i = 0; i < buffNum; ++i)
		{
			glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[i]);
			result.sub_result(BindingPointCheck<api>(_buffers[i]));
		}

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffers[10];
};

template <typename api>
struct CDeleteBindingPoint : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Draw Indirect: Delete binding point";
	}

	virtual std::string Purpose()
	{
		return "Verify that after deleting buffer, binding point is set to correct value";
	}

	virtual std::string Method()
	{
		return "Bind non-zero buffer, delete buffer, check that binding point is set to 0";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if binding point is set to correct value";
	}

	virtual long Run()
	{
		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
		glDeleteBuffers(1, &_buffer);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <typename api>
struct CBufferData : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glBufferData and GetBufferSubData<api>";
	}

	virtual std::string Purpose()
	{
		return "Verify that glBufferData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data using glBufferData" NL
			   "4. Get data using GetBufferSubData<api>" NL "5. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;

		int dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);

		CDataArray dataTest(dataWidth * dataHeight, 0);

		glGenBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
		CDataArray dataRef1;
		DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 0, 50);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0],
					 GL_DYNAMIC_DRAW);
		result.sub_result(BindingPointCheck<api>(_buffers[1]));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		CDataArray dataRef2;
		DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 70);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[2]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
					 GL_STREAM_DRAW);
		result.sub_result(BindingPointCheck<api>(_buffers[2]));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[3]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, 300, NULL, GL_STATIC_DRAW);
		result.sub_result(BindingPointCheck<api>(_buffers[3]));

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[4]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, 400, NULL, GL_DYNAMIC_READ);
		result.sub_result(BindingPointCheck<api>(_buffers[4]));

		CDataArray dataRef5;
		DataGen<unsigned int>(dataRef5, dataWidth, dataHeight, 0, 50);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[5]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef5.size() * sizeof(unsigned int)), &dataRef5[0],
					 GL_STREAM_READ);
		result.sub_result(BindingPointCheck<api>(_buffers[5]));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef5, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		CDataArray dataRef6;
		DataGen<unsigned int>(dataRef6, dataWidth, dataHeight, 10, 40);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[6]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef6.size() * sizeof(unsigned int)), &dataRef6[0],
					 GL_STATIC_READ);
		result.sub_result(BindingPointCheck<api>(_buffers[6]));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef6, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		CDataArray dataRef7;
		DataGen<unsigned int>(dataRef7, dataWidth, dataHeight, 4, 70);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[7]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef7.size() * sizeof(unsigned int)), &dataRef7[0],
					 GL_DYNAMIC_COPY);
		result.sub_result(BindingPointCheck<api>(_buffers[7]));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef7, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[8]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, 800, NULL, GL_STREAM_COPY);
		result.sub_result(BindingPointCheck<api>(_buffers[8]));

		CDataArray dataRef9;
		DataGen<unsigned int>(dataRef9, dataWidth, dataHeight, 18, 35);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[9]);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
					 GL_STATIC_COPY);
		result.sub_result(BindingPointCheck<api>(_buffers[9]));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		//reallocation: same size
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
					 GL_STATIC_COPY);
		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		//reallocation: larger size
		DataGen<unsigned int>(dataRef9, dataWidth * 2, dataHeight * 2, 18, 35);
		dataTest.resize(dataRef9.size());
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
					 GL_STATIC_COPY);
		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(
			DataCompare(dataRef9, dataWidth * 2, dataHeight * 2, dataTest, dataWidth * 2, dataHeight * 2));

		//reallocation: smaller size
		DataGen<unsigned int>(dataRef9, dataWidth / 2, dataHeight / 2, 18, 35);
		dataTest.resize(dataRef9.size());
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
					 GL_STATIC_COPY);
		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(
			DataCompare(dataRef9, dataWidth / 2, dataHeight / 2, dataTest, dataWidth / 2, dataHeight / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffers[10];
};

template <typename api>
struct CBufferSubData : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check function: glBufferSubData and GetBufferSubData<api>";
	}

	virtual std::string Purpose()
	{
		return "Verify that glBufferSubData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer" NL "3. Allocate buffer using glBufferData" NL
			   "4. Set data using glBufferSubData" NL "5. Get data using GetBufferSubData<api>" NL "6. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

		CDataArray dataRef;
		int		   dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 4, 70);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), NULL,
					 GL_DYNAMIC_DRAW);
		glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0]);

		CDataArray dataTest(dataWidth * dataHeight, 0);
		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);

		result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		CDataArray dataSubRef;
		DataGen<unsigned int>(dataSubRef, dataWidth / 2, dataHeight / 2, 80, 90);
		glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 4, (GLsizeiptr)(dataSubRef.size() * sizeof(unsigned int)),
						&dataSubRef[0]);
		std::copy(dataSubRef.begin(), dataSubRef.end(), dataRef.begin() + 1);

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(1, &_buffer);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <typename api>
struct CBufferMap : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glMapBuffer, glUnmapBuffer and getParameteriv";
	}

	virtual std::string Purpose()
	{
		return "Verify that glMapBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL
			   "5. Verify mapped buffer" NL "6. Check state" NL "7. Unmap buffer" NL "8. Check state";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;

		api::GL_Only();

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

		CDataArray dataRef;
		int		   dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
					 GL_DYNAMIC_DRAW);

		result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));

		void* buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY);
		if (buf == 0)
		{
			result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY) returned NULL";
		}

		if (buf)
		{
			result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));

			result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
												 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));

			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;

			result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
		}

		buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY);
		if (buf == 0)
		{
			result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY) returned NULL";
		}

		if (buf)
		{
			result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));

			result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0,
												 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));

			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;

			result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
		}

		buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE);
		if (buf == 0)
		{
			result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE) returned NULL";
		}

		if (buf)
		{
			result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));

			result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_WRITE, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, 0,
												 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));

			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;

			result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
		}

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(1, &_buffer);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <typename api>
struct CBufferGetPointerv : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glBuffergetPointerv";
	}

	virtual std::string Purpose()
	{
		return "Verify that glBuffergetPointerv accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL
			   "5. Get a pointer to buffer" NL "6. Compare pointers from point 4) and 5)" NL
			   "7. Verify mapped buffer" NL "8. Unmap buffer";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

		CDataArray dataRef;
		int		   dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
					 GL_DYNAMIC_DRAW);

		void* ptr = 0;
		glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);

		if (ptr != 0)
		{
			result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned invalid "
							  "pointer, expected: NULL";
		}

		void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
									 GL_MAP_READ_BIT);
		if (buf == 0)
		{
			result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";

			return result.code();
		}

		glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);

		if (ptr == 0)
		{
			result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned NULL";
		}

		if (ptr)
		{
			result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, ptr, dataWidth, dataHeight));
		}

		if (ptr != buf)
		{
			result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) different pointer "
							  "than glMapBuffer(GL_DRAW_INDIRECT_BUFFER)";
		}

		if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
		{
			result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
		}
		buf = 0;
		ptr = 0;

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(1, &_buffer);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <class api>
struct CBufferMapRange : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glMapRangeBuffer, glUnmapBuffer and getParameteriv";
	}

	virtual std::string Purpose()
	{
		return "Verify that glMapRangeBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "Bind non-zero buffer and check that binding point is set to correct value";
	}

	virtual std::string PassCriteria()
	{
		return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer using glMapBufferRange" NL
			   "5. Check state" NL "6. Verify mapped buffer" NL "7. Unmap buffer" NL "8. Check state";
	}

	virtual long Run()
	{
		DIResult result;

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

		CDataArray dataRef;
		int		   dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
					 GL_DYNAMIC_DRAW);

		result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));

		void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
									 GL_MAP_READ_BIT);
		if (buf == 0)
		{
			result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
		}

		if (buf)
		{
			result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));

			result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
												 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));

			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;

			result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
		}

		buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)),
							   GL_MAP_WRITE_BIT);
		if (buf == 0)
		{
			result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
		}

		if (buf)
		{
			result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2));

			result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0,
												 (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));

			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;

			result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
		}

		buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
							   (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)), GL_MAP_WRITE_BIT);
		if (buf == 0)
		{
			result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
		}

		if (buf)
		{
			result.sub_result(
				BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2, dataHeight / 4));

			result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT,
												 (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
												 (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));

			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;

			result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
		}

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(1, &_buffer);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <class api>
struct CBufferFlushMappedRange : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glFlushMappedBufferRange";
	}

	virtual std::string Purpose()
	{
		return "Verify that glFlushMappedBufferRange and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL
			   "4. Map buffer with GL_MAP_FLUSH_EXPLICIT_BIT flag" NL "5. Check state" NL "6. Modify mapped buffer" NL
			   "7. Flush buffer" NL "8. Unmap buffer" NL "9. Check state" NL "10. Verify buffer";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

		CDataArray dataRef;
		int		   dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 1000);

		CDataArray dataRef2;
		DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 1000, 2000);

		const int halfSize	= dataHeight / 2 * dataWidth;
		const int quarterSize = dataHeight / 4 * dataWidth;

		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
					 GL_DYNAMIC_DRAW);

		result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));

		void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, quarterSize * sizeof(unsigned int),
									 halfSize * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);

		if (buf == 0)
		{
			result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
		}

		if (buf)
		{
			result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,
												 quarterSize * sizeof(unsigned int), halfSize * sizeof(unsigned int)));

			memcpy(buf, &dataRef2[quarterSize], halfSize * sizeof(unsigned int));
			glFlushMappedBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, halfSize * sizeof(unsigned int));

			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;

			result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
		}

		CDataArray dataTest(dataWidth * dataHeight, 0);
		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);

		result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));

		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
									  dataHeight / 4, dataHeight / 4));

		result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4,
									  dataHeight * 3 / 4, dataHeight * 3 / 4));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(1, &_buffer);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <class api>
struct CBufferBindRange : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glBindBufferRange";
	}

	virtual std::string Purpose()
	{
		return "Verify that glBindBufferRange accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer using glBindBufferRange" NL "3. Set data" NL "4. Verify buffer";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

		CDataArray dataRef;
		int		   dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 100);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef.size() * sizeof(unsigned int), &dataRef[0], GL_DYNAMIC_DRAW);

		CDataArray dataTest(dataWidth * dataHeight, 0);
		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
		result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
		result.sub_result(BindingPointCheck<api>(0));

		glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, 0, dataTest.size() * sizeof(unsigned int) / 4);
		result.sub_result(BindingPointCheck<api>(_buffer));

		CDataArray dataRef2;
		DataGen<unsigned int>(dataRef2, dataWidth, dataHeight / 2, 10, 15);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 4, &dataRef2[0],
					 GL_DYNAMIC_DRAW);

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));
		result.sub_result(DataCompare(dataRef, dataWidth, dataHeight * 3 / 4, dataTest, dataWidth, dataHeight * 3 / 4,
									  dataHeight / 4, dataHeight / 4));

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
		result.sub_result(BindingPointCheck<api>(0));

		glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, dataTest.size() * sizeof(unsigned int) / 4,
						  dataTest.size() * sizeof(unsigned int) / 4);
		result.sub_result(BindingPointCheck<api>(_buffer));

		glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 2,
					 &dataRef2[dataRef2.size() / 2], GL_DYNAMIC_DRAW);
		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2));
		result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
									  dataHeight / 2, dataHeight / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(1, &_buffer);

		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffer;
};

template <class api>
struct CBufferBindBase : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glBindBufferBase";
	}

	virtual std::string Purpose()
	{
		return "Verify that glBindBufferBase accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer using glBindBufferBase" NL "3. Set data" NL "4. Verify buffer";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;

		glGenBuffers(2, _buffers);

		int dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		CDataArray dataTest(dataWidth * dataHeight, 0);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[0]);
		CDataArray dataRef1;
		DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef1.size() * sizeof(unsigned int), &dataRef1[0], GL_DYNAMIC_DRAW);

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
		result.sub_result(BindingPointCheck<api>(0));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
		result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
		result.sub_result(BindingPointCheck<api>(_buffers[0]));

		glBindBufferBase(GL_DRAW_INDIRECT_BUFFER, 0, _buffers[1]);
		result.sub_result(BindingPointCheck<api>(_buffers[1]));

		CDataArray dataRef2;
		DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 50, 70);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int), &dataRef2[0], GL_DYNAMIC_DRAW);

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		result.sub_result(BindingPointCheck<api>(_buffers[1]));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(2, _buffers);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffers[2];
};

template <class api>
struct CBufferCopySubData : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Check functions: glCopyBufferSubData";
	}

	virtual std::string Purpose()
	{
		return "Verify that glCopyBufferSubData accepts GL_DRAW_INDIRECT_BUFFER enum";
	}

	virtual std::string Method()
	{
		return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Verify buffer" NL
			   "5. Modify buffer using glCopyBufferSubData" NL "6. Verify buffer";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		DIResult result;
		int		 dataWidth, dataHeight;
		getDataSize(dataWidth, dataHeight);
		CDataArray dataTest(dataWidth * dataHeight, 0);

		glGenBuffers(2, _buffers);
		glBindBuffer(GL_ARRAY_BUFFER, _buffers[0]);

		CDataArray dataRef1;
		DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0],
					 GL_DYNAMIC_DRAW);

		GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
		result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]);

		CDataArray dataRef2;
		DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 30);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
					 GL_DYNAMIC_DRAW);

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		glCopyBufferSubData(GL_ARRAY_BUFFER, GL_DRAW_INDIRECT_BUFFER, 0, 0,
							(GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
					 GL_DYNAMIC_DRAW);

		GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
							  &dataTest[0]);
		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		glCopyBufferSubData(GL_DRAW_INDIRECT_BUFFER, GL_ARRAY_BUFFER, 0, 0,
							(GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));

		GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
		result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDeleteBuffers(2, _buffers);
		return BindingPointCheck<api>(0);
	}

private:
	GLuint _buffers[2];
};

class CBasicVertexDef : public DrawIndirectBase
{
public:
	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	template <typename api>
	long Run()
	{
		CColorArray coords;
		PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);

		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenBuffers(1, &_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, _vbo);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand   indirectArrays   = { 0, 0, 0, 0 };
		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			indirectArrays.count			  = static_cast<GLuint>(coords.size());
			indirectArrays.primCount		  = 1;
			indirectArrays.first			  = 0;
			indirectArrays.reservedMustBeZero = 0;

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
				glDrawArraysIndirect(_primitiveType, 0);
				glDeleteBuffers(1, &buffer);
			}
		}
		break;
		case DRAW_ELEMENTS:
		{
			indirectElements.count				= static_cast<GLuint>(coords.size());
			indirectElements.primCount			= 1;
			indirectElements.firstIndex			= 0;
			indirectElements.baseVertex			= 0;
			indirectElements.reservedMustBeZero = 0;

			glGenBuffers(1, &_ebo);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
						 GL_STATIC_DRAW);

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
				glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
				glDeleteBuffers(1, &buffer);
			}
		}
		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);

		DIResult result;
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
		glUseProgram(0);

		if (_vao)
		{
			glDeleteVertexArrays(1, &_vao);
		}
		if (_vbo)
		{
			glDeleteBuffers(1, &_vbo);
		}
		if (_ebo)
		{
			glDeleteBuffers(1, &_ebo);
		}
		if (_program)
		{
			glDeleteProgram(_program);
		}

		return NO_ERROR;
	}

	CBasicVertexDef(TDrawFunction drawFunc, GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY)
		: _drawFunc(drawFunc)
		, _primitiveType(primitiveType)
		, _drawSizeX(drawSizeX)
		, _drawSizeY(drawSizeY)
		, _vao(0)
		, _vbo(0)
		, _ebo(0)
		, _program(0)
	{
	}

private:
	TDrawFunction _drawFunc;
	GLenum		  _primitiveType;
	unsigned int  _drawSizeX;
	unsigned int  _drawSizeY;

	GLuint _vao;
	GLuint _vbo, _ebo;
	GLuint _program;

	CBasicVertexDef()
	{
	}
};

class CBasicVertexInstancingDef : public DrawIndirectBase
{
public:
	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	template <typename api>
	long Run()
	{
		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);

		CColorArray coords_instanced(4);
		coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
		coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
		coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
		coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);

		CColorArray colors_instanced(2);
		colors_instanced[0] = tcu::Vec4(1.0, 0.0, 0.0, 1.0);
		colors_instanced[1] = tcu::Vec4(0.0, 1.0, 0.0, 1.0);

		_program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenBuffers(1, &_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, _vbo);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
												   coords_instanced.size() * sizeof(coords_instanced[0]) +
												   colors_instanced.size() * sizeof(colors_instanced[0])),
					 NULL, GL_STATIC_DRAW);

		const size_t coords_offset			 = 0;
		const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
		const size_t colors_instanced_offset =
			coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);

		glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
		glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
						(GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
		glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)colors_instanced_offset,
						(GLsizeiptr)(colors_instanced.size() * sizeof(colors_instanced[0])), &colors_instanced[0]);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		//i_vertex (coords)
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_offset));
		glEnableVertexAttribArray(0);

		//i_vertex_instanced (coords_instanced)
		glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_instanced_offset));
		glEnableVertexAttribArray(1);
		glVertexAttribDivisor(1, 1);

		//i_vertex_color_instanced (color_instanced)
		glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(colors_instanced_offset));
		glEnableVertexAttribArray(2);
		glVertexAttribDivisor(2, 3);

		DrawArraysIndirectCommand   indirectArrays   = { 0, 0, 0, 0 };
		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			indirectArrays.count			  = static_cast<GLuint>(coords.size());
			indirectArrays.primCount		  = 4;
			indirectArrays.first			  = 0;
			indirectArrays.reservedMustBeZero = 0;

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
				glDrawArraysIndirect(GL_TRIANGLES, 0);
				glDeleteBuffers(1, &buffer);
			}
		}
		break;
		case DRAW_ELEMENTS:
		{
			indirectElements.count				= static_cast<GLuint>(coords.size());
			indirectElements.primCount			= 4;
			indirectElements.firstIndex			= 0;
			indirectElements.baseVertex			= 0;
			indirectElements.reservedMustBeZero = 0;

			glGenBuffers(1, &_ebo);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
						 GL_STATIC_DRAW);

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
				glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
				glDeleteBuffers(1, &buffer);
			}
		}
		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[0]);
		CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[1]);

		CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
		DIResult	result;

		ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
							 &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
							 &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
							 getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
		glUseProgram(0);

		if (_vao)
		{
			glDeleteVertexArrays(1, &_vao);
		}
		if (_vbo)
		{
			glDeleteBuffers(1, &_vbo);
		}
		if (_ebo)
		{
			glDeleteBuffers(1, &_ebo);
		}
		if (_program)
		{
			glDeleteProgram(_program);
		}

		return NO_ERROR;
	}

	template <typename api>
	std::string Vsh()
	{
		return api::glslVer() + NL
			   "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
			   "layout(location = 2) in vec4 i_vertex_color_instanced;" NL "out vec4 vertex_color_instanced;" NL
			   "void main()" NL "{" NL "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
			   "    vertex_color_instanced = i_vertex_color_instanced;" NL "}";
	}

	template <typename api>
	std::string Fsh()
	{
		return api::glslVer() + NL "precision highp float; " NL "in  vec4 vertex_color_instanced;" NL
								   "out vec4 outColor;" NL "void main() {" NL "  outColor = vertex_color_instanced;" NL
								   "}";
	}

	CBasicVertexInstancingDef(TDrawFunction drawFunc)
		: _drawFunc(drawFunc), _drawSizeX(2), _drawSizeY(2), _vao(0), _vbo(0), _ebo(0), _program(0)
	{
	}

private:
	TDrawFunction _drawFunc;
	unsigned int  _drawSizeX;
	unsigned int  _drawSizeY;

	GLuint _vao;
	GLuint _vbo, _ebo;
	GLuint _program;

	CBasicVertexInstancingDef()
	{
	}
};

template <typename api>
class CVBODrawArraysSingle : public CBasicVertexDef
{
public:
	virtual std::string Title()
	{
		return "VBO: Single primitive using glDrawArraysIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
	}

	virtual std::string Method()
	{
		return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawArraysSingle() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 1, 1)
	{
	}
	virtual long Run()
	{
		return CBasicVertexDef::Run<api>();
	}
};

template <typename api>
class CVBODrawArraysMany : public CBasicVertexDef
{
public:
	virtual std::string Title()
	{
		return "VBO: Many primitives using glDrawArraysIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
	}

	virtual std::string Method()
	{
		return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawArraysMany() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 8, 8)
	{
	}
	virtual long Run()
	{
		return CBasicVertexDef::Run<api>();
	}
};

template <typename api>
class CVBODrawArraysInstancing : public CBasicVertexInstancingDef
{
public:
	virtual std::string Title()
	{
		return "VBO: Single primitive using glDrawArraysIndirect, multiple instances";
	}

	virtual std::string Purpose()
	{
		return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
	}

	virtual std::string Method()
	{
		return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawArraysInstancing() : CBasicVertexInstancingDef(DRAW_ARRAYS)
	{
	}
	virtual long Run()
	{
		return CBasicVertexInstancingDef::Run<api>();
	}
};

class CBasicXFBPausedDef : public DrawIndirectBase
{
public:
	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	template <typename api>
	long Run()
	{
		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);

		_program = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);

		const GLchar* varyings[] = { "dataOut" };
		glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
		glLinkProgram(_program);
		if (!CheckProgram(_program))
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenBuffers(1, &_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, _vbo);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand   indirectArrays   = { 0, 0, 0, 0 };
		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenTransformFeedbacks(1, &_xfo);
		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);

		glGenBuffers(1, &_xfbo);
		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfbo);
		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STATIC_DRAW);
		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfbo);

		glBeginTransformFeedback(GL_TRIANGLES);
		glPauseTransformFeedback();

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			indirectArrays.count			  = static_cast<GLuint>(coords.size());
			indirectArrays.primCount		  = 1;
			indirectArrays.first			  = 0;
			indirectArrays.reservedMustBeZero = 0;

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
				glDrawArraysIndirect(GL_TRIANGLES, 0);
				glDeleteBuffers(1, &buffer);
			}
		}
		break;
		case DRAW_ELEMENTS:
		{
			indirectElements.count				= static_cast<GLuint>(coords.size());
			indirectElements.primCount			= 1;
			indirectElements.firstIndex			= 0;
			indirectElements.baseVertex			= 0;
			indirectElements.reservedMustBeZero = 0;

			glGenBuffers(1, &_ebo);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
						 GL_STATIC_DRAW);

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
				glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
				glDeleteBuffers(1, &buffer);
			}
		}

		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		glResumeTransformFeedback();
		glEndTransformFeedback();

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);

		DIResult result;
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
		glUseProgram(0);

		if (_vao)
		{
			glDeleteVertexArrays(1, &_vao);
		}
		if (_vbo)
		{
			glDeleteBuffers(1, &_vbo);
		}
		if (_ebo)
		{
			glDeleteBuffers(1, &_ebo);
		}
		if (_xfbo)
		{
			glDeleteBuffers(1, &_xfbo);
		}
		if (_program)
		{
			glDeleteProgram(_program);
		}
		if (_xfo)
		{
			glDeleteTransformFeedbacks(1, &_xfo);
		}

		return NO_ERROR;
	}

	template <typename api>
	std::string Vsh()
	{
		return api::glslVer() + NL "in vec4 i_vertex;" NL "out vec4 dataOut;" NL "void main()" NL "{" NL
								   "    gl_Position = i_vertex;" NL "    dataOut = i_vertex;" NL "}";
	}

	CBasicXFBPausedDef(TDrawFunction drawFunc)
		: _drawFunc(drawFunc), _drawSizeX(2), _drawSizeY(2), _vao(0), _vbo(0), _ebo(0), _xfbo(0), _program(0), _xfo(0)
	{
	}

private:
	TDrawFunction _drawFunc;
	unsigned int  _drawSizeX;
	unsigned int  _drawSizeY;

	GLuint _vao;
	GLuint _vbo, _ebo, _xfbo;
	GLuint _program;
	GLuint _xfo;

	CBasicXFBPausedDef()
	{
	}
};

template <typename api>
class CVBODrawArraysXFBPaused : public CBasicXFBPausedDef
{
public:
	virtual std::string Title()
	{
		return "VBO: glDrawArraysIndirect, in paused transform feedback operation";
	}

	virtual std::string Purpose()
	{
		return "Verify  glDrawArraysIndirect works, if XFB is active and paused";
	}

	virtual std::string Method()
	{
		return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawArraysXFBPaused() : CBasicXFBPausedDef(DRAW_ARRAYS)
	{
	}
	virtual long Run()
	{
		return CBasicXFBPausedDef::Run<api>();
	}
};

template <typename api>
class CVBODrawElementsSingle : public CBasicVertexDef
{
public:
	virtual std::string Title()
	{
		return "VBO: Single primitive using glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawElementsSingle() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 1, 1)
	{
	}
	virtual long Run()
	{
		return CBasicVertexDef::Run<api>();
	}
};

template <typename api>
class CVBODrawElementsMany : public CBasicVertexDef
{
public:
	virtual std::string Title()
	{
		return "VBO: Many primitives using glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawElementsMany() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 8, 8)
	{
	}

	virtual long Run()
	{
		return CBasicVertexDef::Run<api>();
	}
};

template <typename api>
class CVBODrawElementsInstancing : public CBasicVertexInstancingDef
{
public:
	virtual std::string Title()
	{
		return "VBO: Single primitive using glDrawElementsIndirect, multiple instances";
	}

	virtual std::string Purpose()
	{
		return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawElementsInstancing() : CBasicVertexInstancingDef(DRAW_ELEMENTS)
	{
	}
	virtual long Run()
	{
		return CBasicVertexInstancingDef::Run<api>();
	}
};

template <typename api>
class CVBODrawElementsXFBPaused : public CBasicXFBPausedDef
{
public:
	virtual std::string Title()
	{
		return "VBO: glDrawElementsIndirect, in paused transform feedback operation";
	}

	virtual std::string Purpose()
	{
		return "Verify  glDrawElementsIndirect works, if XFB is active and paused";
	}

	virtual std::string Method()
	{
		return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CVBODrawElementsXFBPaused() : CBasicXFBPausedDef(DRAW_ELEMENTS)
	{
	}
	virtual long Run()
	{
		return CBasicXFBPausedDef::Run<api>();
	}
};

template <typename api>
class CBufferIndirectDrawArraysSimple : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawArraysIndirect: many primitives simple";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;
		indirectArrays.first					 = 0;
		indirectArrays.reservedMustBeZero		 = 0;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		glDrawArraysIndirect(GL_TRIANGLES, 0);

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawArraysNoFirst : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawArraysIndirect: non-zero 'first' argument";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with specified non-zero 'first' argument" NL
			   "in indirect buffer";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size()) / 2;
		indirectArrays.primCount				 = 1;
		indirectArrays.first					 = static_cast<GLuint>(coords.size()) / 2;
		indirectArrays.reservedMustBeZero		 = 0;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		glDrawArraysIndirect(GL_TRIANGLES, 0);

		CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
										 getWindowWidth(), getWindowHeight() / 2));

		ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
										 getWindowWidth(), getWindowHeight() / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawArraysOffset : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawArraysIndirect: offset as a function parameter";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with offset as a function parameter";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect with offset" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;
		indirectArrays.first					 = 0;
		indirectArrays.reservedMustBeZero		 = 0;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
		glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), sizeof(DrawArraysIndirectCommand),
						&indirectArrays);
		glDrawArraysIndirect(GL_TRIANGLES, (void*)sizeof(DrawArraysIndirectCommand));

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawElementsSimple : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawElementsIndirect: many primitives simple";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;
		indirectElements.baseVertex					 = 0;
		indirectElements.firstIndex					 = 0;
		indirectElements.reservedMustBeZero			 = 0;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		glDeleteBuffers(1, &_ebo);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect, _ebo;
};

template <typename api>
class CBufferIndirectDrawElementsNoFirstIndex : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawElementsIndirect: non-zero first index";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with non-zero first index" NL "in indirect buffer";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size()) / 2;
		indirectElements.primCount					 = 1;
		indirectElements.baseVertex					 = 0;
		indirectElements.firstIndex					 = static_cast<GLuint>(coords.size()) / 2;
		indirectElements.reservedMustBeZero			 = 0;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

		CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
										 getWindowWidth(), getWindowHeight() / 2));

		ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
										 getWindowWidth(), getWindowHeight() / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect, _ebo;
};

template <typename api>
class CBufferIndirectDrawElementsNoBasevertex : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawElementsIndirect: non-zero base vertex";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with non-zero base vertex" NL "in indirect buffer";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size()) / 2;
		indirectElements.primCount					 = 1;
		indirectElements.baseVertex					 = static_cast<GLint>(coords.size()) / 2;
		indirectElements.firstIndex					 = 0;
		indirectElements.reservedMustBeZero			 = 0;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

		CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
										 getWindowWidth(), getWindowHeight() / 2));

		ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
										 getWindowWidth(), getWindowHeight() / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawElementsOffset : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawElementsIndirect: offset as a function parameter";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with offset as a function parameter";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect with offset" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;
		indirectElements.baseVertex					 = 0;
		indirectElements.firstIndex					 = 0;
		indirectElements.reservedMustBeZero			 = 0;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
		glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand),
						sizeof(DrawElementsIndirectCommand), &indirectElements);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);
		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void*)sizeof(DrawElementsIndirectCommand));

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

class CBasicVertexIDsDef : public DrawIndirectBase
{
public:
	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	template <typename api>
	long Run()
	{
		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);

		CColorArray coords_instanced(4);
		coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
		coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
		coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
		coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);

		std::vector<glw::GLfloat> ref_VertexId(coords.size());
		for (size_t i = 0; i < ref_VertexId.size(); i++)
		{
			ref_VertexId[i] = glw::GLfloat(i);
		}

		std::vector<glw::GLfloat> ref_InstanceId(4);
		for (size_t i = 0; i < ref_InstanceId.size(); i++)
		{
			ref_InstanceId[i] = glw::GLfloat(i);
		}

		_program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenBuffers(1, &_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, _vbo);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
												   coords_instanced.size() * sizeof(coords_instanced[0]) +
												   ref_VertexId.size() * sizeof(ref_VertexId[0]) +
												   ref_InstanceId.size() * sizeof(ref_InstanceId[0])),
					 NULL, GL_STATIC_DRAW);

		const size_t coords_offset			 = 0;
		const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
		const size_t ref_VertexId_offset =
			coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);
		const size_t ref_InstanceId_offset = ref_VertexId_offset + ref_VertexId.size() * sizeof(ref_VertexId[0]);

		glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
		glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
						(GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
		glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_VertexId_offset,
						(GLsizeiptr)(ref_VertexId.size() * sizeof(ref_VertexId[0])), &ref_VertexId[0]);
		glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_InstanceId_offset,
						(GLsizeiptr)(ref_InstanceId.size() * sizeof(ref_InstanceId[0])), &ref_InstanceId[0]);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		//i_vertex (coords)
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_offset));
		glEnableVertexAttribArray(0);

		//i_vertex_instanced (coords_instanced)
		glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_instanced_offset));
		glEnableVertexAttribArray(1);
		glVertexAttribDivisor(1, 1);

		//i_ref_VertexId
		glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(ref_VertexId_offset));
		glEnableVertexAttribArray(2);
		//i_ref_InstanceId
		glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(ref_InstanceId_offset));
		glEnableVertexAttribArray(3);
		glVertexAttribDivisor(3, 1);

		DrawArraysIndirectCommand   indirectArrays   = { 0, 0, 0, 0 };
		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			indirectArrays.count			  = static_cast<GLuint>(coords.size());
			indirectArrays.primCount		  = 4;
			indirectArrays.first			  = 0;
			indirectArrays.reservedMustBeZero = 0;

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
				glDrawArraysIndirect(GL_TRIANGLES, 0);
				glDeleteBuffers(1, &buffer);
			}
		}
		break;
		case DRAW_ELEMENTS:
		{
			indirectElements.count				= static_cast<GLuint>(coords.size());
			indirectElements.primCount			= 4;
			indirectElements.firstIndex			= 0;
			indirectElements.baseVertex			= 0;
			indirectElements.reservedMustBeZero = 0;

			glGenBuffers(1, &_ebo);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
						 GL_STATIC_DRAW);

			{
				GLuint buffer;
				glGenBuffers(1, &buffer);
				glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
				glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
				glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
				glDeleteBuffers(1, &buffer);
			}
		}
		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.5f, 0.0f));
		CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.75f, 0.0f));
		CColorArray bufferRef3(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.25f, 0.0f));
		CColorArray bufferRef4(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.0f, 0.0f));

		CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
		DIResult	result;

		ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
							 &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
							 &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef3,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
							 getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef4,
										 getWindowWidth() / 2, getWindowHeight() / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
		glUseProgram(0);

		if (_vao)
		{
			glDeleteVertexArrays(1, &_vao);
		}
		if (_vbo)
		{
			glDeleteBuffers(1, &_vbo);
		}
		if (_ebo)
		{
			glDeleteBuffers(1, &_ebo);
		}
		if (_program)
		{
			glDeleteProgram(_program);
		}

		return NO_ERROR;
	}

	template <typename api>
	std::string Vsh()
	{
		return api::glslVer() + NL
			   "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
			   "layout(location = 2) in float i_ref_VertexId;" NL "layout(location = 3) in float i_ref_InstanceId;" NL
			   "out vec4 val_Result;" NL "void main()" NL "{" NL
			   "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
			   "    if ( gl_VertexID == int(i_ref_VertexId + .5) && gl_InstanceID == int(i_ref_InstanceId + .5)) {" NL
			   "        val_Result = vec4(0.0, 1.0, float(gl_InstanceID) / 4.0, 1.0);" NL "    } else {" NL
			   "        val_Result = vec4(1.0, 0.0, 0.0, 1.0);" NL "    }" NL "}";
	}

	template <typename api>
	std::string Fsh()
	{
		return api::glslVer() + NL "precision highp float; " NL "in vec4 val_Result;" NL "out vec4 outColor;" NL
								   "void main() {" NL "  outColor = val_Result;" NL "}";
	}

	CBasicVertexIDsDef(TDrawFunction drawFunc)
		: _drawFunc(drawFunc), _drawSizeX(2), _drawSizeY(2), _vao(0), _vbo(0), _ebo(0), _program(0)
	{
	}

private:
	TDrawFunction _drawFunc;
	unsigned int  _drawSizeX;
	unsigned int  _drawSizeY;

	GLuint _vao;
	GLuint _vbo, _ebo;
	GLuint _program;

	CBasicVertexIDsDef()
	{
	}
};

template <typename api>
class CBufferIndirectDrawArraysVertexIds : public CBasicVertexIDsDef
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawArraysIndirect: all non-zero arguments, verify vertex ids";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		return CBasicVertexIDsDef::Run<api>();
	}

	CBufferIndirectDrawArraysVertexIds() : CBasicVertexIDsDef(DRAW_ARRAYS)
	{
	}
};

template <typename api>
class CBufferIndirectDrawElementsVertexIds : public CBasicVertexIDsDef
{
public:
	virtual std::string Title()
	{
		return "Indirect buffer glDrawElementsIndirect: all non-zero arguments, verify vertex ids";
	}

	virtual std::string Purpose()
	{
		return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Run()
	{
		return CBasicVertexIDsDef::Run<api>();
	}

	CBufferIndirectDrawElementsVertexIds() : CBasicVertexIDsDef(DRAW_ELEMENTS)
	{
	}
};

template <typename api>
class CIndicesDataTypeUnsignedShort : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect indices data type: unsigned short";
	}

	virtual std::string Purpose()
	{
		return "Verify that unsigned short indices are accepted by glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
			   "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size()) / 2;
		indirectElements.primCount					 = 1;
		indirectElements.baseVertex					 = -static_cast<GLint>(coords.size()) / 4;
		indirectElements.firstIndex					 = static_cast<GLuint>(coords.size()) / 4;
		indirectElements.reservedMustBeZero			 = 0;

		std::vector<GLushort> elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLushort>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
		glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0);

		CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
										 getWindowWidth(), getWindowHeight() / 2));

		ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
										 getWindowWidth(), getWindowHeight() / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
class CIndicesDataTypeUnsignedByte : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect indices data type: unsigned byte";
	}

	virtual std::string Purpose()
	{
		return "Verify that unsigned byte indices are accepted by glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
			   "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 2, 2, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size()) / 2;
		indirectElements.primCount					 = 1;
		indirectElements.baseVertex					 = -static_cast<GLint>(coords.size()) / 4;
		indirectElements.firstIndex					 = static_cast<GLuint>(coords.size()) / 4;
		indirectElements.reservedMustBeZero			 = 0;

		std::vector<GLubyte> elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLubyte>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
		glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_BYTE, 0);

		CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
										 getWindowWidth(), getWindowHeight() / 2));

		ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
										 getWindowWidth(), getWindowHeight() / 2));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

class CPrimitiveMode : public DrawIndirectBase
{
public:
	template <typename api>
	bool IsGeometryShaderSupported()
	{
		if (api::isES())
		{
			const glu::ContextInfo& info = m_context.getContextInfo();
			const glu::ContextType& type = m_context.getRenderContext().getType();

			/* ES 3.2+ included geometry shaders into the core */
			if (glu::contextSupports(type, glu::ApiType(3, 2, glu::PROFILE_ES)))
			{
				return true;
			}
			/* ES 3.1 may be able to support geometry shaders via extensions */
			else if ((glu::contextSupports(type, glu::ApiType(3, 1, glu::PROFILE_ES))) &&
					 ((true == info.isExtensionSupported("GL_EXT_geometry_shader")) ||
					  (true == info.isExtensionSupported("GL_OES_geometry_shader"))))
			{
				return true;
			}
			else
			{
				OutputNotSupported("Geometry shader is not supported\n");
				return false;
			}
		}
		else
		{
			return true;
		}
	}
	virtual long Setup()
	{
		_sizeX = getWindowWidth();
		_sizeY = getWindowHeight();
		if (_primitiveType != GL_TRIANGLE_STRIP && _primitiveType != GL_TRIANGLE_STRIP_ADJACENCY &&
			_primitiveType != GL_TRIANGLES && _primitiveType != GL_TRIANGLES_ADJACENCY &&
			_primitiveType != GL_TRIANGLE_FAN)
		{
			_sizeX &= (-4);
			_sizeY &= (-4);
		}
		if ((int)_drawSizeX < 0 || (int)_drawSizeY < 0)
		{
			//no PrimitiveGen dimensions given. assume same dimensions as rendered image^
			_drawSizeX = _sizeX;
			_drawSizeY = _sizeY;
			if (_primitiveType == GL_POINTS)
			{
				//clamp vertex number (and rendering size) for points to max. 10000
				_sizeX = _drawSizeX = std::min(_drawSizeX, 100u);
				_sizeY = _drawSizeY = std::min(_drawSizeY, 100u);
			}
		}

		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	template <typename api>
	long Run(bool pointMode = false)
	{

		glClear(GL_COLOR_BUFFER_BIT);

		_program = CreateProgram(pointMode ? shaders::vshSimple_point<api>() : shaders::vshSimple<api>(), "",
								 shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		CColorArray padding(10, tcu::Vec4(0.0f));

		glBufferData(GL_ARRAY_BUFFER,
					 (GLsizeiptr)(coords.size() * (sizeof(coords[0])) + padding.size() * (sizeof(padding[0]))), NULL,
					 GL_STREAM_DRAW);
		glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(padding.size() * (sizeof(padding[0]))), &padding[0]);
		glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(padding.size() * (sizeof(padding[0]))),
						(GLsizeiptr)(coords.size() * (sizeof(coords[0]))), &coords[0]);

		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		DrawArraysIndirectCommand   indirectArrays   = { 0, 0, 0, 0 };

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			indirectArrays.count			  = static_cast<GLuint>(coords.size()) / 2;
			indirectArrays.primCount		  = 1;
			indirectArrays.first			  = 10;
			indirectArrays.reservedMustBeZero = 0;

			glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), NULL, GL_STATIC_DRAW);
			glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), &indirectArrays);

			glDrawArraysIndirect(_primitiveType, 0);
		}
		break;
		case DRAW_ELEMENTS:
		{
			indirectElements.count				= static_cast<GLuint>(coords.size()) / 2;
			indirectElements.primCount			= 1;
			indirectElements.baseVertex			= 7;
			indirectElements.firstIndex			= 3;
			indirectElements.reservedMustBeZero = 0;

			glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
			glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);

			glGenBuffers(1, &_ebo);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
						 GL_STATIC_DRAW);

			glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
		}
		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		CColorArray bufferRef1(_sizeX * _sizeY / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		CColorArray bufferRef2(_sizeX * _sizeY / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(_sizeX * _sizeY, tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, (_sizeY + 1) / 2, _sizeX, _sizeY / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef1, _sizeX, _sizeY / 2));

		switch (_primitiveType)
		{
		case GL_TRIANGLES_ADJACENCY:
		case GL_TRIANGLE_STRIP_ADJACENCY:
		{
			CColorArray bufferRef3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
			CColorArray bufferRef4(_sizeX * _sizeY / 8, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
			CColorArray bufferRef5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));

			CColorArray bufferTest3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f));
			CColorArray bufferTest4(_sizeX * _sizeY / 8, tcu::Vec4(0.0f));
			CColorArray bufferTest5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f));

			ReadPixelsFloat<api>(0, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
			result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));

			ReadPixelsFloat<api>((_sizeX + 3) / 4, (_sizeY + 3) / 4, _sizeX / 2, _sizeY / 4, &bufferTest4[0]);
			result.sub_result(BuffersCompare(bufferTest4, _sizeX / 2, _sizeY / 4, bufferRef4, _sizeX / 2, _sizeY / 4));

			ReadPixelsFloat<api>((_sizeX * 3 + 3) / 4, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
			result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));

			ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 4, &bufferTest5[0]);
			result.sub_result(BuffersCompare(bufferTest5, _sizeX, _sizeY / 4, bufferRef5, _sizeX, _sizeY / 4));
		}
		break;
		default:
		{
			ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 2, &bufferTest[0]);
			result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef2, _sizeX, _sizeY / 2));
		}
		break;
		}

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

	CPrimitiveMode(TDrawFunction drawFunc, GLenum primitiveType, unsigned int sizeX = -1, unsigned sizeY = -1)
		: _drawFunc(drawFunc)
		, _primitiveType(primitiveType)
		, _drawSizeX(sizeX)
		, _drawSizeY(sizeY)
		, _sizeX(0)
		, _sizeY(0)
		, _program(0)
		, _vao(0)
		, _buffer(0)
		, _ebo(0)
		, _bufferIndirect(0)
	{
	}

private:
	TDrawFunction _drawFunc;
	GLenum		  _primitiveType;
	unsigned int  _drawSizeX, _drawSizeY; //dims for primitive generator
	unsigned int  _sizeX, _sizeY;		  //rendering size
	GLuint		  _program;
	GLuint		  _vao, _buffer, _ebo, _bufferIndirect;

	CPrimitiveMode();
};

template <typename api>
class CModeDrawArraysPoints : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_POINTS";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_POINTS works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysPoints() : CPrimitiveMode(DRAW_ARRAYS, GL_POINTS)
	{
	}

	virtual long Run()
	{
		return CPrimitiveMode::Run<api>(true);
	}
};

template <typename api>
class CModeDrawArraysLines : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_LINES";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_LINES works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysLines() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES)
	{
	}

	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysLineStrip : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_LINE_STRIP";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_LINE_STRIP works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysLineStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP)
	{
	}
	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysLineLoop : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_LINE_LOOP";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_LINE_LOOP works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysLineLoop() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_LOOP)
	{
	}

	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysTriangleStrip : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysTriangleStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP, 2, 2)
	{
	}

	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysTriangleFan : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_TRIANGLE_FAN";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_TRIANGLE_FAN works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysTriangleFan() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_FAN, 2, 2)
	{
	}

	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysLinesAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_LINES_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_LINES_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysLinesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES_ADJACENCY)
	{
	}

	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysLineStripAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_LINE_STRIP_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysLineStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP_ADJACENCY)
	{
	}

	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysTrianglesAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_TRIANGLES_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_TRIANGLES_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysTrianglesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLES_ADJACENCY, 4, 4)
	{
	}

	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawArraysTriangleStripAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawArraysTriangleStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
	{
	}
	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsPoints : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_POINTS";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_POINTS works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsPoints() : CPrimitiveMode(DRAW_ELEMENTS, GL_POINTS)
	{
	}

	virtual long Run()
	{
		return CPrimitiveMode::Run<api>(true);
	}
};

template <typename api>
class CModeDrawElementsLines : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_LINES";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_LINES works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsLines() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES)
	{
	}
	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsLineStrip : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_LINE_STRIP";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_LINE_STRIP works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsLineStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP)
	{
	}
	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsLineLoop : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_LINE_LOOP";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_LINE_LOOP works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsLineLoop() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_LOOP)
	{
	}
	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsTriangleStrip : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsTriangleStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP, 2, 2)
	{
	}
	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsTriangleFan : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_TRIANGLE_FAN";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_TRIANGLE_FAN works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsTriangleFan() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_FAN, 2, 2)
	{
	}
	virtual long Run()
	{
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsLinesAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_LINES_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_LINES_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsLinesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES_ADJACENCY)
	{
	}
	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsLineStripAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_LINE_STRIP_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsLineStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP_ADJACENCY)
	{
	}
	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsTrianglesAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_TRIANGLES_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_TRIANGLES_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsTrianglesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLES_ADJACENCY, 4, 4)
	{
	}
	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

template <typename api>
class CModeDrawElementsTriangleStripAdjacency : public CPrimitiveMode
{
public:
	virtual std::string Title()
	{
		return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
	}

	virtual std::string Purpose()
	{
		return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
	}

	virtual std::string Method()
	{
		return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
			   "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CModeDrawElementsTriangleStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
	{
	}
	virtual long Run()
	{
		if (!IsGeometryShaderSupported<api>())
			return NOT_SUPPORTED;
		return CPrimitiveMode::Run<api>();
	}
};

class CTransformFeedback : public DrawIndirectBase
{
public:
	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	template <typename api>
	long Run()
	{
		CColorArray coords;
		PrimitiveGen(GL_TRIANGLE_STRIP, 8, 8, coords);

		glClear(GL_COLOR_BUFFER_BIT);

		_program				 = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);
		const GLchar* varyings[] = { "dataOut" };
		glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
		glLinkProgram(_program);
		if (!CheckProgram(_program))
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenBuffers(1, &_vbo);
		glBindBuffer(GL_ARRAY_BUFFER, _vbo);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);

		glGenBuffers(1, &_ubo);
		glBindBuffer(GL_UNIFORM_BUFFER, _ubo);
		glBufferData(GL_UNIFORM_BUFFER, 4 * 5 * sizeof(GLuint), NULL, GL_STATIC_DRAW);
		glBindBufferBase(GL_UNIFORM_BUFFER, glGetUniformBlockIndex(_program, "BLOCK"), _ubo);
		std::vector<GLuint> uboData;

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			uboData.resize(4 * 4, 0);

			uboData[0]  = static_cast<GLuint>(coords.size()); //count
			uboData[4]  = 1;								  //primcount
			uboData[8]  = 0;								  //first
			uboData[12] = 0;								  //mbz
		}
		break;
		case DRAW_ELEMENTS:
		{
			uboData.resize(4 * 5, 0);
			uboData[0]  = static_cast<GLuint>(coords.size()); //count
			uboData[4]  = 1;								  //primcount
			uboData[8]  = 0;								  //firstindex
			uboData[12] = 0;								  //basevertex
			uboData[16] = 0;								  //mbz
		}
		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}
		glBufferSubData(GL_UNIFORM_BUFFER, 0, (GLsizeiptr)(uboData.size() * sizeof(uboData[0])), &uboData[0]);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		glGenBuffers(1, &_bufferIndirect);

		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _bufferIndirect);
		GLuint zeroes[] = { 0, 0, 0, 0, 0 };
		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(zeroes), zeroes, GL_DYNAMIC_DRAW);
		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);

		glEnable(GL_RASTERIZER_DISCARD);
		glBeginTransformFeedback(GL_POINTS);
		glDrawArrays(GL_POINTS, 0, 5);
		glEndTransformFeedback();
		glDisable(GL_RASTERIZER_DISCARD);

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
			glDrawArraysIndirect(GL_TRIANGLES, 0);
			break;
		case DRAW_ELEMENTS:
			glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

			break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);

		DIResult result;
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
		glUseProgram(0);

		if (_vao)
		{
			glDeleteVertexArrays(1, &_vao);
		}
		if (_vbo)
		{
			glDeleteBuffers(1, &_vbo);
		}
		if (_ebo)
		{
			glDeleteBuffers(1, &_ebo);
		}
		if (_ubo)
		{
			glDeleteBuffers(1, &_ubo);
		}
		if (_bufferIndirect)
		{
			glDeleteBuffers(1, &_bufferIndirect);
		}
		if (_program)
		{
			glDeleteProgram(_program);
		}
		return NO_ERROR;
	}

	CTransformFeedback(TDrawFunction drawFunc)
		: _drawFunc(drawFunc), _program(0), _vao(0), _vbo(0), _ebo(0), _ubo(0), _bufferIndirect(0)
	{
	}

private:
	TDrawFunction _drawFunc;
	GLuint		  _program;
	GLuint		  _vao, _vbo, _ebo, _ubo, _bufferIndirect;

	CTransformFeedback();

	template <typename api>
	std::string Vsh()
	{
		return api::glslVer() + NL "flat out highp uint dataOut;" NL "in vec4 i_vertex;" NL
								   "layout(std140) uniform  BLOCK {" NL " uint m[5];" NL "} b;" NL "void main() {" NL
								   "  dataOut = b.m[min(4, gl_VertexID)];" NL "    gl_Position = i_vertex;" NL "}";
	}
};

template <typename api>
struct CTransformFeedbackArray : public CTransformFeedback
{
	virtual std::string Title()
	{
		return "Transform feedback: glDrawArrayIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that transform feedback works correctly with glDrawArrayIndirect";
	}

	virtual std::string Method()
	{
		return "1. Create data" NL "2. Use data as input to glDrawArrayIndirect" NL "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CTransformFeedbackArray() : CTransformFeedback(DRAW_ARRAYS)
	{
	}

	virtual long Run()
	{
		return CTransformFeedback::Run<api>();
	}
};

template <typename api>
struct CTransformFeedbackElements : public CTransformFeedback
{
	virtual std::string Title()
	{
		return "Transform feedback: glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that transform feedback works correctly with glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Create data" NL "2. Use data as input to glDrawElementsIndirect" NL "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CTransformFeedbackElements() : CTransformFeedback(DRAW_ELEMENTS)
	{
	}

	virtual long Run()
	{
		return CTransformFeedback::Run<api>();
	}
};

class CComputeBase : public DrawIndirectBase
{
public:
	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	template <typename api>
	long Run()
	{

		int width, height;
		glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &width);
		glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &height);

		width  = std::min(width, getWindowWidth());
		height = std::min(height, getWindowHeight());

		glViewport(0, 0, width, height);

		CColorArray coords(width * height, tcu::Vec4(0));
		CColorArray colors(width * height, tcu::Vec4(0));

		_program = CreateProgram(Vsh<api>(), "", Fsh<api>(), false);
		glBindAttribLocation(_program, 0, "in_coords");
		glBindAttribLocation(_program, 1, "in_colors");
		glLinkProgram(_program);
		if (!CheckProgram(_program))
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_bufferCoords);
		glBindBuffer(GL_ARRAY_BUFFER, _bufferCoords);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), 0, GL_STREAM_DRAW);

		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
		glEnableVertexAttribArray(0);

		glGenBuffers(1, &_bufferColors);
		glBindBuffer(GL_ARRAY_BUFFER, _bufferColors);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(colors.size() * sizeof(colors[0])), 0, GL_STREAM_DRAW);

		glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
		glEnableVertexAttribArray(1);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		DrawArraysIndirectCommand   indirectArrays   = { 0, 0, 0, 0 };

		CElementArray elements(width * height, 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
		}
		break;
		case DRAW_ELEMENTS:
		{
			glGenBuffers(1, &_ebo);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
						 GL_STATIC_DRAW);

			glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements,
						 GL_STATIC_DRAW);
		}
		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		_programCompute = CreateComputeProgram(Csh<api>(), false);
		glLinkProgram(_programCompute);
		if (!CheckProgram(_programCompute))
		{
			return ERROR;
		}
		glUseProgram(_programCompute);
		glUniform1ui(glGetUniformLocation(_programCompute, "width"), width);
		glUniform1ui(glGetUniformLocation(_programCompute, "height"), height);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, _bufferCoords);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, _bufferColors);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, _bufferIndirect);

		glDispatchCompute(width, height, 1);
		glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);

		glUseProgram(_program);

		switch (_drawFunc)
		{
		case DRAW_ARRAYS:
		{
			glDrawArraysIndirect(GL_POINTS, 0);
		}
		break;
		case DRAW_ELEMENTS:
		{
			glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, 0);
		}
		break;
		default:
			throw std::runtime_error("Unknown draw function!");
			break;
		}

		CColorArray bufferRef1(width * height / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
		CColorArray bufferRef2(width * height / 4, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
		CColorArray bufferRef3(width * height / 4, tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f));
		CColorArray bufferRef4(width * height / 4, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
		CColorArray bufferTest(width * height / 4, tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, width / 2, height / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef1, width / 2, height / 2))
			<< "Region 0 verification failed";

		ReadPixelsFloat<api>((width + 1) / 2, 0, width / 2, height / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef2, width / 2, height / 2))
			<< "Region 1 verification failed";

		ReadPixelsFloat<api>(0, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef3, width / 2, height / 2))
			<< "Region 2 verification failed";

		ReadPixelsFloat<api>((width + 1) / 2, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef4, width / 2, height / 2))
			<< "Region 3 verification failed";

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(1);
		glDisableVertexAttribArray(0);
		glDeleteProgram(_program);
		glDeleteProgram(_programCompute);
		glDeleteVertexArrays(1, &_vao);
		if (_ebo)
			glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferCoords);
		glDeleteBuffers(1, &_bufferColors);
		glDeleteBuffers(1, &_bufferIndirect);
		glViewport(0, 0, getWindowWidth(), getWindowHeight());
		return NO_ERROR;
	}
	CComputeBase(TDrawFunction drawFunc)
		: _drawFunc(drawFunc)
		, _program(0)
		, _programCompute(0)
		, _vao(0)
		, _ebo(0)
		, _bufferCoords(0)
		, _bufferColors(0)
		, _bufferIndirect(0)
	{
	}

private:
	CComputeBase();
	TDrawFunction _drawFunc;

	template <typename api>
	std::string Vsh()
	{
		return api::glslVer() + NL "in vec4 in_coords;" NL "in vec4 in_colors;" NL "out vec4 colors;" NL
								   "void main() {" NL "  colors = in_colors;" NL "  gl_Position = in_coords;" NL
								   "#if defined(GL_ES)" NL "  gl_PointSize = 1.0;" NL "#endif" NL "}";
	}

	template <typename api>
	std::string Fsh()
	{
		return api::glslVer() + NL "precision highp float;" NL "in vec4 colors;" NL "out vec4 outColor;" NL
								   "void main() {" NL "  outColor = colors;" NL "}";
	}

	template <typename api>
	std::string Csh()
	{
		return api::glslVer(true) + NL "precision highp int;                                           " NL
									   "precision highp float;                                         " NL
									   "                                                               " NL
									   "layout(local_size_x = 1) in;                                   " NL
									   "layout(std430, binding = 0) buffer Vertices {                  " NL
									   "    vec4 vertices[];                                           " NL
									   "};                                                             " NL
									   "layout(std430, binding = 1) buffer Colors {                    " NL
									   "    vec4 colors[];                                             " NL
									   "};                                                             " NL
									   "layout(std430, binding = 2) buffer Indirect {                  " NL
									   "    uint indirect[4];                                          " NL
									   "};                                                             " NL
									   "                                                               " NL
									   "uniform uint height;                                           " NL
									   "uniform uint width;                                            " NL
									   "                                                               " NL
									   "void main() {                                                  " NL
									   "    uint w = gl_GlobalInvocationID.x;                          " NL
									   "    uint h = gl_GlobalInvocationID.y;                          " NL
									   "    float stepX = 2.0 / float(width);                          " NL
									   "    float stepY = 2.0 / float(height);                         " NL
									   "    float offsetX = -1.0 + stepX * float(w) + stepX / 2.0;     " NL
									   "    float offsetY = -1.0 + stepY * float(h) + stepY / 2.0;     " NL
									   "    uint arrayOffset = h * width + w;                          " NL
									   "    vertices[ arrayOffset ] = vec4(offsetX, offsetY, 0.0, 1.0);" NL
									   "    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);                     " NL
									   "    if(w > (width / 2u - 1u)) {                                " NL
									   "        color = color + vec4(0.5, 0.0, 0.0, 0.0);              " NL
									   "    }                                                          " NL
									   "    if(h > (height / 2u - 1u)) {                               " NL
									   "        color = color + vec4(0.0, 0.5, 0.0, 0.0);              " NL
									   "    }                                                          " NL
									   "    colors[ arrayOffset ] = color;                             " NL
									   "    if(w == 0u && h == 0u) {                                   " NL
									   "        indirect[0] = width * height;                          " NL
									   "        indirect[1] =  1u;                                     " NL
									   "    }                                                          " NL
									   "}                                                              ";
	}

	GLuint _program, _programCompute;
	GLuint _vao;
	GLuint _ebo;
	GLuint _bufferCoords;
	GLuint _bufferColors;
	GLuint _bufferIndirect;
};

template <typename api>
struct CComputeShaderArray : public CComputeBase
{
	virtual std::string Title()
	{
		return "Compute Shader: glDrawArrayIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that data created by Compute Shader can be used as an input to glDrawArrayIndirect";
	}

	virtual std::string Method()
	{
		return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawArrayIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CComputeShaderArray() : CComputeBase(DRAW_ARRAYS)
	{
	}

	virtual long Run()
	{
		return CComputeBase::Run<api>();
	}
};

template <typename api>
struct CComputeShaderElements : public CComputeBase
{
	virtual std::string Title()
	{
		return "Compute Shader: glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that data created by Compute Shader can be used as an input to glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawElementsIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	CComputeShaderElements() : CComputeBase(DRAW_ELEMENTS)
	{
	}

	virtual long Run()
	{
		return CComputeBase::Run<api>();
	}
};

template <typename api>
class CPrimitiveRestartElements : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Primitive restart - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that primitive restart works correctly with glDrawElementsIndirect";
	}

	virtual std::string Method()
	{
		return "1. Define primitives using VBO" NL "2. Draw primitives using glDrawElementsIndirect" NL
			   "3. Verify results";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if no OpenGL errors reported";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	int PrimitiveRestartIndex();

	void EnablePrimitiveRestart();

	void DisablePrimitiveRestart();

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords1;
		TriangleStipGen(coords1, -1.0f, 1.0f, -1.0, -0.5, 2);

		CColorArray coords2;
		TriangleStipGen(coords2, -1.0f, 1.0f, 0.5, 1.0, 4);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords1.size() + coords2.size()) * sizeof(coords1[0]), NULL,
					 GL_STREAM_DRAW);
		glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(coords1.size() * sizeof(coords1[0])), &coords1[0]);
		glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(coords1.size() * sizeof(coords1[0])),
						(GLsizeiptr)(coords2.size() * sizeof(coords2[0])), &coords2[0]);
		glVertexAttribPointer(0, sizeof(coords1[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords1[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords1.size() + coords2.size() + 1);
		indirectElements.primCount					 = static_cast<GLuint>((coords1.size() + coords2.size()) / 2);

		CElementArray elements;
		for (size_t i = 0; i < coords1.size(); ++i)
		{
			elements.push_back(static_cast<GLuint>(i));
		}

		elements.push_back(PrimitiveRestartIndex());
		for (size_t i = 0; i < coords2.size(); ++i)
		{
			elements.push_back(static_cast<GLuint>(coords1.size() + i));
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		EnablePrimitiveRestart();

		glDrawElementsIndirect(GL_TRIANGLE_STRIP, GL_UNSIGNED_INT, 0);

		CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
		CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));
		CColorArray bufferTest1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.0f));
		CColorArray bufferTest2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));

		DIResult result;
		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 4, &bufferTest1[0]);
		result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
										 getWindowWidth(), getWindowHeight() / 4));
		// height = 2 * (getWindowHeight() / 4)  to avoid border pixels
		// in case the height is not a multiple of 4.
		ReadPixelsFloat<api>(0, (getWindowHeight() + 3) / 4, getWindowWidth(), 2 * (getWindowHeight() / 4), &bufferTest2[0]);
		result.sub_result(BuffersCompare(bufferTest2, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
										 getWindowWidth(), 2 *(getWindowHeight() / 4)));

		ReadPixelsFloat<api>(0, (getWindowHeight() * 3 + 3) / 4, getWindowWidth(), getWindowHeight() / 4,
							 &bufferTest1[0]);
		result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
										 getWindowWidth(), getWindowHeight() / 4));

		return result.code();
	}

	virtual long Cleanup()
	{

		DisablePrimitiveRestart();
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	void TriangleStipGen(CColorArray& coords, float widthStart, float widthEnd, float heightStart, float heightEnd,
						 unsigned int primNum)
	{
		float widthStep  = (widthEnd - widthStart) / static_cast<float>(primNum);
		float heightStep = (heightEnd - heightStart) / static_cast<float>(primNum);
		for (unsigned int i = 0; i < primNum; ++i)
		{
			float heightOffset = heightStart + heightStep * static_cast<float>(i);
			for (unsigned int j = 0; j < primNum; ++j)
			{
				float widthOffset = widthStart + widthStep * static_cast<float>(j);

				coords.push_back(tcu::Vec4(widthOffset, heightOffset, 0.0f, 1.0f));
				coords.push_back(tcu::Vec4(widthOffset, heightOffset + heightStep, 0.0f, 1.0f));
				coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset, 0.0f, 1.0f));
				coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset + heightStep, 0.0f, 1.0f));
			}
		}
	}
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <>
int CPrimitiveRestartElements<test_api::ES3>::PrimitiveRestartIndex()
{
	return 0xffffffff;
}

template <>
int CPrimitiveRestartElements<test_api::GL>::PrimitiveRestartIndex()
{
	return 3432432;
}

template <>
void CPrimitiveRestartElements<test_api::ES3>::DisablePrimitiveRestart()
{
	glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
}

template <>
void CPrimitiveRestartElements<test_api::GL>::DisablePrimitiveRestart()
{
	glDisable(GL_PRIMITIVE_RESTART);
}

template <>
void CPrimitiveRestartElements<test_api::ES3>::EnablePrimitiveRestart()
{
	glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
}

template <>
void CPrimitiveRestartElements<test_api::GL>::EnablePrimitiveRestart()
{
	glPrimitiveRestartIndex(PrimitiveRestartIndex());
	glEnable(GL_PRIMITIVE_RESTART);
}

template <typename api>
struct CNegativeZeroBufferArray : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: no indirect buffer/parameter - glDrawArrayIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call glDrawArrayIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);
		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);

		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		glDrawArraysIndirect(GL_TRIANGLES, 0);
		DIResult result;
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer;
};

template <typename api>
struct CNegativeZeroBufferElements : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: no indirect buffer/parameter - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call glDrawElementsIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

		DIResult result;
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo;
};

template <typename api>
struct CNegativeInvalidModeArray : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: invalid mode - glDrawArrayIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Set invalid mode to glDrawArrayIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		glDrawArraysIndirect(GL_FLOAT, 0);

		DIResult result;
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
		}

		glDrawArraysIndirect(GL_STATIC_DRAW, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW as mode";
		}

		glDrawArraysIndirect(GL_DRAW_INDIRECT_BUFFER, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_DRAW_INDIRECT_BUFFER as mode";
		}

		glDrawArraysIndirect(GL_INVALID_ENUM, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM as mode";
		}

		glDrawArraysIndirect(GL_COLOR_BUFFER_BIT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_COLOR_BUFFER_BIT as mode";
		}

		glDrawArraysIndirect(GL_ARRAY_BUFFER, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_ARRAY_BUFFER as mode";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeInvalidModeElements : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: invalid mode - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Set invalid mode to glDrawElemenetsIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;
		glDrawElementsIndirect(GL_INVALID_ENUM, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
		}

		glDrawElementsIndirect(GL_UNSIGNED_INT, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_UNSIGNED_INT as mode";
		}

		glDrawElementsIndirect(GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_ELEMENT_ARRAY_BUFFER as mode";
		}

		glDrawElementsIndirect(GL_FASTEST, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_FASTEST as mode";
		}

		glDrawElementsIndirect(GL_PACK_ALIGNMENT, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_PACK_ALIGNMENT as mode";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVAOArrays : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: no VAO - glDrawArraysIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Use glDrawArraysIndirect with default VAO";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		DIResult result;
		glDrawArraysIndirect(GL_TRIANGLES, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver";
		}

		if (glu::isContextTypeES(m_context.getRenderContext().getType()))
			glDisableVertexAttribArray(0);

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{

		if (glu::isContextTypeES(m_context.getRenderContext().getType()))
			glDisableVertexAttribArray(0);

		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVAOElements : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: no VAO - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Use glDrawElemenetsIndirect with default VAO";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;
		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver";
		}

		if (glu::isContextTypeES(m_context.getRenderContext().getType()))
			glDisableVertexAttribArray(0);

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVBOArrays : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: no VBO - glDrawArraysIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Use glDrawArraysIndirect with enabled vertex array, that has no VBO bound";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		DIResult result;
		glDrawArraysIndirect(GL_TRIANGLES, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver";
		}

		glDisableVertexAttribArray(0);

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVBOElements : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: no VBO - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Use glDrawElementsIndirect with enabled vertex array, that has no VBO bound";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{

		api::ES_Only();

		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);
		glEnableVertexAttribArray(0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;
		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver";
		}

		glDisableVertexAttribArray(0);

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeBufferMappedArray : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: buffer mapped - glDrawArraysIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawArrayIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		DIResult result;
		void*	buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), GL_MAP_READ_BIT);
		if (buf == 0)
		{
			result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
		}

		glDrawArraysIndirect(GL_TRIANGLES, 0);

		GLenum error = glGetError();
		if (error == GL_INVALID_OPERATION)
		{
			//GL error: nothing is rendered
			CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
			CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

			ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
			result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
											 getWindowWidth(), getWindowHeight()));
		}
		else if (error == GL_NO_ERROR)
		{
			//No GL error: undefined
		}
		else
		{
			result.error() << "Invalid error code returned by a driver";
		}

		if (buf)
		{
			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;
		}

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeBufferMappedElements : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: buffer mapped - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawElementsIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;
		void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT);
		if (buf == 0)
		{
			result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

		GLenum error = glGetError();
		if (error == GL_INVALID_OPERATION)
		{
			//GL error: nothing is rendered
			CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
			CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

			ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
			result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
											 getWindowWidth(), getWindowHeight()));
		}
		else if (error == GL_NO_ERROR)
		{
			//No GL error: undefined
		}
		else
		{
			result.error() << "Invalid error code returned by a driver";
		}

		if (buf)
		{
			if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
			{
				result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
			}
			buf = 0;
		}

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeDataWrongElements : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: invalid type - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "1. Bind non-zero buffer" NL "2. Call glDrawElementsIndirect with invalid type";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;

		glDrawElementsIndirect(GL_TRIANGLES, GL_FLOAT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_FLOAT type";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_INT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_INT type";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_STATIC_DRAW, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW type";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_SHORT, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_SHORT type";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_BYTE, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_BYTE type";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_DOUBLE, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_DOUBLE type";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_INVALID_ENUM, 0);
		if (glGetError() != GL_INVALID_ENUM)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM type";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
class CNegativeGshArray : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Negative: incompatible the input primitive type of gsh - glDrawArrayIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
			   "4. Call glDrawArrayIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;
		indirectArrays.first					 = 0;
		indirectArrays.reservedMustBeZero		 = 0;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		DIResult result;

		glDrawArraysIndirect(GL_POINTS, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	std::string Vsh()
	{
		return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
	}

	std::string Gsh()
	{
		return "#version 150" NL "layout(triangles) in;" NL "layout(triangle_strip, max_vertices = 10) out;" NL
			   "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
			   "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
	}

	std::string Fsh()
	{
		return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
			   "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
	}
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CNegativeGshElements : public DrawIndirectBase
{
public:
	virtual std::string Title()
	{
		return "Negative: incompatible the input primitive type of gsh - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
			   "4. Call glDrawElementsIndirect";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	std::string Vsh()
	{
		return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
	}

	std::string Gsh()
	{
		return "#version 150" NL "layout(lines) in;" NL "layout(line_strip, max_vertices = 10) out;" NL
			   "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
			   "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
	}

	std::string Fsh()
	{
		return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
			   "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
	}
	int	_program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeInvalidSizeArrays : public DrawIndirectBase
{
	struct TWrongStructure1
	{
		GLuint count;
		GLuint primCount;
	};

	struct TWrongStructure2
	{
		GLfloat count;
		GLuint  primCount;
	};

	virtual std::string Title()
	{
		return "Negative: wrong structure - glDrawArrayIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call glDrawArrayIndirect with wrong structure";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		TWrongStructure1 indirectArrays = { 0, 0 };
		indirectArrays.count			= static_cast<GLuint>(coords.size());
		indirectArrays.primCount		= 1;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure1), &indirectArrays, GL_STATIC_DRAW);

		DIResult result;

		glDrawArraysIndirect(GL_TRIANGLES, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		glDeleteBuffers(1, &_bufferIndirect);

		TWrongStructure2 indirectArrays2 = { 0, 0 };
		indirectArrays2.count			 = static_cast<GLfloat>(coords.size());
		indirectArrays2.primCount		 = 1;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure2), &indirectArrays2, GL_STATIC_DRAW);

		glDrawArraysIndirect(GL_TRIANGLES, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeInvalidSizeElements : public DrawIndirectBase
{
	struct TWrongStructure
	{
		GLfloat count;
		GLuint  primCount;
	};

	virtual std::string Title()
	{
		return "Negative: wrong structure - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call glDrawElementsIndirect with wrong structure";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectElements = { 0, 0, 0, 0 };
		indirectElements.count					   = static_cast<GLuint>(coords.size());
		indirectElements.primCount				   = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		TWrongStructure indirectElements2 = { 0, 0 };
		indirectElements2.count			  = static_cast<GLfloat>(coords.size());
		indirectElements2.primCount		  = 1;

		glDeleteBuffers(1, &_bufferIndirect);
		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure), &indirectElements2, GL_STATIC_DRAW);

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeStructureWrongOffsetArray : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: wrong offset - glDrawArrayIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call glDrawArrayIndirect with wrong offset";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 };
		indirectArrays.count					 = static_cast<GLuint>(coords.size());
		indirectArrays.primCount				 = 1;

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

		DIResult result;

		glDrawArraysIndirect(GL_TRIANGLES, (void*)(sizeof(DrawArraysIndirectCommand) * 2));
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		glDrawArraysIndirect(GL_TRIANGLES, (void*)(sizeof(GLuint)));
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeStructureWrongOffsetElements : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: wrong offset - glDrawElementsIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call glDrawElementsIndirect with wrong structure";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Setup()
	{
		glClear(GL_COLOR_BUFFER_BIT);
		return NO_ERROR;
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		CColorArray coords;
		PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);

		glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
		glEnableVertexAttribArray(0);

		DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 };
		indirectElements.count						 = static_cast<GLuint>(coords.size());
		indirectElements.primCount					 = 1;

		CElementArray elements(coords.size(), 0);
		for (size_t i = 0; i < elements.size(); ++i)
		{
			elements[i] = static_cast<GLuint>(i);
		}

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
					 GL_STATIC_DRAW);

		DIResult result;

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void*)(sizeof(DrawElementsIndirectCommand) * 2));
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void*)(sizeof(GLuint)));
		if (glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}

		CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
		CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

		ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
		result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
										 getWindowHeight()));

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeUnalignedOffset : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: unaligned offset - glDrawElementsIndirect and glDrawArraysIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no system/driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call with unaligned offset (1, 3, 1023)";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Run()
	{
		_program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
		if (!_program)
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		std::vector<GLuint> zarro(4096, 0);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);
		glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(0);

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

		DIResult result;

		int offsets[] = { 1, 3, 1023 };
		for (size_t i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++)
		{
			glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, reinterpret_cast<void*>((deUintptr)offsets[i]));
			if (glGetError() != GL_INVALID_VALUE)
			{
				result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
			}
			glDrawArraysIndirect(GL_TRIANGLES, reinterpret_cast<void*>((deUintptr)offsets[i]));
			if (glGetError() != GL_INVALID_VALUE)
			{
				result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
			}
		}

		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		return NO_ERROR;
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeXFB : public DrawIndirectBase
{
	virtual std::string Title()
	{
		return "Negative: transform feedback active and not paused - glDrawElementsIndirect and glDrawArraysIndirect";
	}

	virtual std::string Purpose()
	{
		return "Verify that a driver sets error and no system/driver crash occurred";
	}

	virtual std::string Method()
	{
		return "Call with transform feedback active";
	}

	virtual std::string PassCriteria()
	{
		return "The test will pass if OpenGL errors reported and no driver crash occurred";
	}

	virtual long Run()
	{
		api::ES_Only();

		bool drawWithXFBAllowed = m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader");

		_program				 = CreateProgram(Vsh(), "", shaders::fshSimple<api>(), false);
		const GLchar* varyings[] = { "dataOut" };
		glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
		glLinkProgram(_program);
		if (!CheckProgram(_program))
		{
			return ERROR;
		}
		glUseProgram(_program);

		glGenVertexArrays(1, &_vao);
		glBindVertexArray(_vao);

		std::vector<GLuint> zarro(4096, 0);

		glGenBuffers(1, &_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, _buffer);
		glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(0);

		glGenBuffers(1, &_bufferIndirect);
		glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
		glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

		glGenBuffers(1, &_ebo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

		glGenBuffers(1, &_xfb);
		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfb);
		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);

		DIResult result;

		//Without XFO
		glBeginTransformFeedback(GL_POINTS);

		glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
		if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}
		glDrawArraysIndirect(GL_POINTS, NULL);
		if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}
		glEndTransformFeedback();

		//With XFO
		glGenTransformFeedbacks(1, &_xfo);
		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);
		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);
		glBeginTransformFeedback(GL_POINTS);
		glPauseTransformFeedback();
		glResumeTransformFeedback();

		glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
		if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}
		glDrawArraysIndirect(GL_POINTS, NULL);
		if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
		{
			result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
		}
		glEndTransformFeedback();

		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
		return result.code();
	}

	virtual long Cleanup()
	{
		glDisableVertexAttribArray(0);
		glUseProgram(0);
		glDeleteProgram(_program);
		glDeleteVertexArrays(1, &_vao);
		glDeleteBuffers(1, &_buffer);
		glDeleteBuffers(1, &_ebo);
		glDeleteBuffers(1, &_bufferIndirect);
		glDeleteBuffers(1, &_xfb);
		glDeleteTransformFeedbacks(1, &_xfo);
		return NO_ERROR;
	}

	std::string Vsh()
	{
		return api::glslVer() + NL "out highp vec4 dataOut;" NL "in vec4 i_vertex;" NL "void main() {" NL
								   "  dataOut = i_vertex;" NL "  gl_Position = i_vertex;" NL "}";
	}

private:
	GLuint _program;
	GLuint _vao, _buffer, _ebo, _bufferIndirect, _xfo, _xfb;
};

} // namespace
DrawIndirectTestsGL40::DrawIndirectTestsGL40(glcts::Context& context) : TestCaseGroup(context, "draw_indirect", "")
{
}

DrawIndirectTestsGL40::~DrawIndirectTestsGL40(void)
{
}

void DrawIndirectTestsGL40::init()
{
	using namespace glcts;

	DILogger::setOutput(m_context.getTestContext().getLog());

	addChild(
		new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::GL> >));
	addChild(
		new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::GL> >));
	addChild(
		new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::GL> >));

	addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-buffer-unMap", TestSubcase::Create<CBufferMap<test_api::GL> >));
	addChild(
		new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
							 TestSubcase::Create<CBufferFlushMappedRange<test_api::GL> >));
	addChild(
		new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::GL> >));

	addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
							 TestSubcase::Create<CVBODrawArraysSingle<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
							 TestSubcase::Create<CVBODrawArraysMany<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
							 TestSubcase::Create<CVBODrawArraysInstancing<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
							 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
							 TestSubcase::Create<CVBODrawElementsSingle<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
							 TestSubcase::Create<CVBODrawElementsMany<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
							 TestSubcase::Create<CVBODrawElementsInstancing<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
							 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL> >));

	addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
							 TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
							 TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
							 TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
							 TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-simple",
							 TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
							 TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
							 TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
							 TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
							 TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::GL> >));

	addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
							 TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
							 TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::GL> >));

	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
							 TestSubcase::Create<CModeDrawArraysPoints<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
							 TestSubcase::Create<CModeDrawArraysLines<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
							 TestSubcase::Create<CModeDrawArraysLineStrip<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
							 TestSubcase::Create<CModeDrawArraysLineLoop<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
							 TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
							 TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
							 TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
							 TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
							 TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
							 TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::GL> >));

	addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
							 TestSubcase::Create<CModeDrawElementsPoints<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
							 TestSubcase::Create<CModeDrawElementsLines<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
							 TestSubcase::Create<CModeDrawElementsLineStrip<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
							 TestSubcase::Create<CModeDrawElementsLineLoop<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
							 TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
							 TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
							 TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
							 TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
							 TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::GL> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
							 TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::GL> >));

	addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
							 TestSubcase::Create<CTransformFeedbackArray<test_api::GL> >));
	addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
							 TestSubcase::Create<CTransformFeedbackElements<test_api::GL> >));

	addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
							 TestSubcase::Create<CPrimitiveRestartElements<test_api::GL> >));

	addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
							 TestSubcase::Create<CNegativeZeroBufferArray<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-noindirect-elements",
							 TestSubcase::Create<CNegativeZeroBufferElements<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
							 TestSubcase::Create<CNegativeInvalidModeArray<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
							 TestSubcase::Create<CNegativeInvalidModeElements<test_api::GL> >));
	addChild(
		new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-noVAO-elements",
							 TestSubcase::Create<CNegativeNoVAOElements<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
							 TestSubcase::Create<CNegativeBufferMappedArray<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
							 TestSubcase::Create<CNegativeBufferMappedElements<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-invalidType-elements",
							 TestSubcase::Create<CNegativeDataWrongElements<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-gshIncompatible-arrays",
							 TestSubcase::Create<CNegativeGshArray<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-gshIncompatible-elements",
							 TestSubcase::Create<CNegativeGshElements<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
							 TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
							 TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
							 TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
							 TestSubcase::Create<CNegativeInvalidSizeElements<test_api::GL> >));
	addChild(new TestSubcase(m_context, "negative-unalignedOffset",
							 TestSubcase::Create<CNegativeUnalignedOffset<test_api::GL> >));
}

DrawIndirectTestsGL43::DrawIndirectTestsGL43(glcts::Context& context) : TestCaseGroup(context, "draw_indirect_43", "")
{
}

DrawIndirectTestsGL43::~DrawIndirectTestsGL43(void)
{
}

void DrawIndirectTestsGL43::init()
{
	using namespace glcts;

	DILogger::setOutput(m_context.getTestContext().getLog());
	addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
							 TestSubcase::Create<CComputeShaderArray<test_api::GL> >));
	addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
							 TestSubcase::Create<CComputeShaderElements<test_api::GL> >));
}

DrawIndirectTestsES31::DrawIndirectTestsES31(glcts::Context& context) : TestCaseGroup(context, "draw_indirect", "")
{
}

DrawIndirectTestsES31::~DrawIndirectTestsES31(void)
{
}

void DrawIndirectTestsES31::init()
{
	using namespace glcts;

	DILogger::setOutput(m_context.getTestContext().getLog());

	addChild(
		new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::ES3> >));
	addChild(
		new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::ES3> >));
	addChild(
		new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::ES3> >));
	addChild(
		new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-buffer-getPointerv",
							 TestSubcase::Create<CBufferGetPointerv<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
							 TestSubcase::Create<CBufferFlushMappedRange<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-buffer-copySubData",
							 TestSubcase::Create<CBufferCopySubData<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
							 TestSubcase::Create<CVBODrawArraysSingle<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
							 TestSubcase::Create<CVBODrawArraysMany<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
							 TestSubcase::Create<CVBODrawArraysInstancing<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
							 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
							 TestSubcase::Create<CVBODrawElementsSingle<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
							 TestSubcase::Create<CVBODrawElementsMany<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
							 TestSubcase::Create<CVBODrawElementsInstancing<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
							 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
							 TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
							 TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
							 TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
							 TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-simple",
							 TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
							 TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
							 TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
							 TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
							 TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
							 TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
							 TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
							 TestSubcase::Create<CModeDrawArraysPoints<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
							 TestSubcase::Create<CModeDrawArraysLines<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
							 TestSubcase::Create<CModeDrawArraysLineStrip<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
							 TestSubcase::Create<CModeDrawArraysLineLoop<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
							 TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
							 TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
							 TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
							 TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
							 TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
							 TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
							 TestSubcase::Create<CModeDrawElementsPoints<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
							 TestSubcase::Create<CModeDrawElementsLines<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
							 TestSubcase::Create<CModeDrawElementsLineStrip<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
							 TestSubcase::Create<CModeDrawElementsLineLoop<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
							 TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
							 TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
							 TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
							 TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
							 TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
							 TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
							 TestSubcase::Create<CTransformFeedbackArray<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
							 TestSubcase::Create<CTransformFeedbackElements<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
							 TestSubcase::Create<CComputeShaderArray<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
							 TestSubcase::Create<CComputeShaderElements<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
							 TestSubcase::Create<CPrimitiveRestartElements<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
							 TestSubcase::Create<CNegativeZeroBufferArray<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-noindirect-elements",
							 TestSubcase::Create<CNegativeZeroBufferElements<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
							 TestSubcase::Create<CNegativeInvalidModeArray<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
							 TestSubcase::Create<CNegativeInvalidModeElements<test_api::ES3> >));
	addChild(
		new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-noVAO-elements",
							 TestSubcase::Create<CNegativeNoVAOElements<test_api::ES3> >));
	addChild(
		new TestSubcase(m_context, "negative-noVBO-arrays", TestSubcase::Create<CNegativeNoVBOArrays<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-noVBO-elements",
							 TestSubcase::Create<CNegativeNoVBOElements<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
							 TestSubcase::Create<CNegativeBufferMappedArray<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
							 TestSubcase::Create<CNegativeBufferMappedElements<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-invalidType-elements",
							 TestSubcase::Create<CNegativeDataWrongElements<test_api::ES3> >));

	addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
							 TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
							 TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
							 TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
							 TestSubcase::Create<CNegativeInvalidSizeElements<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-unalignedOffset",
							 TestSubcase::Create<CNegativeUnalignedOffset<test_api::ES3> >));
	addChild(new TestSubcase(m_context, "negative-xfb", TestSubcase::Create<CNegativeXFB<test_api::ES3> >));
}
}
