/*-------------------------------------------------------------------------
 * 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!");
		}
		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!");
		}
	}

	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";
		case GL_READ_ONLY:
			return "GL_READ_ONLY";
		case GL_WRITE_ONLY:
			return "GL_WRITE_ONLY";
		default:
			throw std::runtime_error("Invalid access type!");
		}
	}
};

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> >));
}
}
