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

#include "es31fVertexAttributeBindingTests.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluRenderContext.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "gluObjectWrapper.hpp"
#include "gluStrUtil.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deStringUtil.hpp"
#include "deInt32.h"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

static const char* const s_colorFragmentShader =		"#version 310 es\n"
														"in mediump vec4 v_color;\n"
														"layout(location = 0) out mediump vec4 fragColor;\n"
														"void main (void)\n"
														"{\n"
														"	fragColor = v_color;\n"
														"}\n";

static const char* const s_positionColorShader =		"#version 310 es\n"
														"in highp vec4 a_position;\n"
														"in highp vec4 a_color;\n"
														"out highp vec4 v_color;\n"
														"void main (void)\n"
														"{\n"
														"	gl_Position = a_position;\n"
														"	v_color = a_color;\n"
														"}\n";

static const char* const s_positionColorOffsetShader =	"#version 310 es\n"
														"in highp vec4 a_position;\n"
														"in highp vec4 a_offset;\n"
														"in highp vec4 a_color;\n"
														"out highp vec4 v_color;\n"
														"void main (void)\n"
														"{\n"
														"	gl_Position = a_position + a_offset;\n"
														"	v_color = a_color;\n"
														"}\n";

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

	const int colorThreshold	= 20;

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

	log << TestLog::Message << "Verifying image contents." << TestLog::EndMessage;

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

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

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

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

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

		if (logImageOnSuccess)
			log << TestLog::ImageSet("Verfication result", "Result of rendering")
				<< TestLog::Image("Result", "Result", image)
				<< TestLog::EndImageSet;
	}

	return isOk;
}

class BindingRenderCase : public TestCase
{
public:
	enum
	{
		TEST_RENDER_SIZE = 64
	};

						BindingRenderCase	(Context& ctx, const char* name, const char* desc, bool unalignedData);
	virtual				~BindingRenderCase	(void);

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

private:
	virtual void		renderTo			(tcu::Surface& dst) = 0;
	virtual void		createBuffers		(void) = 0;
	virtual void		createShader		(void) = 0;

protected:
	const bool			m_unalignedData;
	glw::GLuint			m_vao;
	glu::ShaderProgram*	m_program;
};

BindingRenderCase::BindingRenderCase (Context& ctx, const char* name, const char* desc, bool unalignedData)
	: TestCase			(ctx, name, desc)
	, m_unalignedData	(unalignedData)
	, m_vao				(0)
	, m_program			(DE_NULL)
{
}

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

void BindingRenderCase::init (void)
{
	// check requirements
	if (m_context.getRenderTarget().getWidth() < TEST_RENDER_SIZE || m_context.getRenderTarget().getHeight() < TEST_RENDER_SIZE)
		throw tcu::NotSupportedError("Test requires at least " + de::toString<int>(TEST_RENDER_SIZE) + "x" + de::toString<int>(TEST_RENDER_SIZE) + " render target");

	// resources
	m_context.getRenderContext().getFunctions().genVertexArrays(1, &m_vao);
	if (m_context.getRenderContext().getFunctions().getError() != GL_NO_ERROR)
		throw tcu::TestError("could not gen vao");

	createBuffers();
	createShader();
}

void BindingRenderCase::deinit (void)
{
	if (m_vao)
	{
		m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vao);
		m_vao = 0;
	}

	delete m_program;
	m_program = DE_NULL;
}

BindingRenderCase::IterateResult BindingRenderCase::iterate (void)
{
	tcu::Surface surface(TEST_RENDER_SIZE, TEST_RENDER_SIZE);

	// draw pattern

	renderTo(surface);

	// verify results

	if (verifyImageYellowGreen(surface, m_testCtx.getLog(), false))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else if (m_unalignedData)
		m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned data");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");

	return STOP;
}

class SingleBindingCase : public BindingRenderCase
{
public:

	enum CaseFlag
	{
		FLAG_ATTRIB_UNALIGNED			= (1<<0),		// !< unalign attributes with relativeOffset
		FLAG_ATTRIB_ALIGNED				= (1<<1),		// !< align attributes with relativeOffset to the buffer begin (and not buffer offset)
		FLAG_ATTRIBS_MULTIPLE_ELEMS		= (1<<2),		// !< use multiple attribute elements
		FLAG_ATTRIBS_SHARED_ELEMS		= (1<<3),		// !< use multiple shared attribute elements. xyzw & rgba stored as (x, y, zr, wg, b, a)

		FLAG_BUF_ALIGNED_OFFSET			= (1<<4),		// !< use aligned offset to the buffer object
		FLAG_BUF_UNALIGNED_OFFSET		= (1<<5),		// !< use unaligned offset to the buffer object
		FLAG_BUF_UNALIGNED_STRIDE		= (1<<6),		// !< unalign buffer elements
	};
						SingleBindingCase	(Context& ctx, const char* name, int flags);
						~SingleBindingCase	(void);

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

private:
	struct TestSpec
	{
		int		bufferOffset;
		int		bufferStride;
		int		positionAttrOffset;
		int		colorAttrOffset;
		bool	hasColorAttr;
	};

	enum
	{
		GRID_SIZE = 20
	};

	void				renderTo			(tcu::Surface& dst);

	static TestSpec		genTestSpec			(int flags);
	static std::string	genTestDescription	(int flags);
	static bool			isDataUnaligned		(int flags);

	void				createBuffers		(void);
	void				createShader		(void);
	std::string			genVertexSource		(void);

	const TestSpec		m_spec;
	glw::GLuint			m_buf;
};

SingleBindingCase::SingleBindingCase (Context& ctx, const char* name, int flags)
	: BindingRenderCase	(ctx, name, genTestDescription(flags).c_str(), isDataUnaligned(flags))
	, m_spec			(genTestSpec(flags))
	, m_buf				(0)
{
	DE_ASSERT(!((flags & FLAG_ATTRIB_UNALIGNED) && (flags & FLAG_ATTRIB_ALIGNED)));
	DE_ASSERT(!((flags & FLAG_ATTRIB_ALIGNED) && (flags & FLAG_BUF_UNALIGNED_STRIDE)));

	DE_ASSERT(!isDataUnaligned(flags));
}

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

void SingleBindingCase::init (void)
{
	// log what we are trying to do

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Rendering " << (int)GRID_SIZE << "x" << (int)GRID_SIZE << " grid.\n"
						<< "Buffer format:\n"
						<< "	bufferOffset: " << m_spec.bufferOffset << "\n"
						<< "	bufferStride: " << m_spec.bufferStride << "\n"
						<< "Vertex position format:\n"
						<< "	type: float4\n"
						<< "	offset: " << m_spec.positionAttrOffset << "\n"
						<< "	total offset: " << m_spec.bufferOffset + m_spec.positionAttrOffset << "\n"
						<< tcu::TestLog::EndMessage;

	if (m_spec.hasColorAttr)
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Color:\n"
							<< "	type: float4\n"
							<< "	offset: " << m_spec.colorAttrOffset << "\n"
							<< "	total offset: " << m_spec.bufferOffset + m_spec.colorAttrOffset << "\n"
							<< tcu::TestLog::EndMessage;
	// init

	BindingRenderCase::init();
}

void SingleBindingCase::deinit (void)
{
	if (m_buf)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buf);
		m_buf = 0;
	}

	BindingRenderCase::deinit();
}

void SingleBindingCase::renderTo (tcu::Surface& dst)
{
	glu::CallLogWrapper gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	const int			positionLoc		= gl.glGetAttribLocation(m_program->getProgram(), "a_position");
	const int			colorLoc		= gl.glGetAttribLocation(m_program->getProgram(), "a_color");
	const int			colorUniformLoc	= gl.glGetUniformLocation(m_program->getProgram(), "u_color");

	gl.enableLogging(true);

	gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	gl.glClear(GL_COLOR_BUFFER_BIT);
	gl.glViewport(0, 0, dst.getWidth(), dst.getHeight());
	gl.glBindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "set vao");

	gl.glUseProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "use program");

	if (m_spec.hasColorAttr)
	{
		gl.glBindVertexBuffer(3, m_buf, m_spec.bufferOffset, m_spec.bufferStride);

		gl.glVertexAttribBinding(positionLoc, 3);
		gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, m_spec.positionAttrOffset);
		gl.glEnableVertexAttribArray(positionLoc);

		gl.glVertexAttribBinding(colorLoc, 3);
		gl.glVertexAttribFormat(colorLoc, 4, GL_FLOAT, GL_FALSE, m_spec.colorAttrOffset);
		gl.glEnableVertexAttribArray(colorLoc);

		GLU_EXPECT_NO_ERROR(gl.glGetError(), "set va");

		gl.glDrawArrays(GL_TRIANGLES, 0, GRID_SIZE*GRID_SIZE*6);
		GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");
	}
	else
	{
		gl.glBindVertexBuffer(3, m_buf, m_spec.bufferOffset, m_spec.bufferStride);
		gl.glVertexAttribBinding(positionLoc, 3);
		gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, m_spec.positionAttrOffset);
		gl.glEnableVertexAttribArray(positionLoc);

		GLU_EXPECT_NO_ERROR(gl.glGetError(), "set va");
		gl.glUniform4f(colorUniformLoc, 0.0f, 1.0f, 0.0f, 1.0f);

		gl.glDrawArrays(GL_TRIANGLES, 0, GRID_SIZE*GRID_SIZE*6);
		GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");
	}

	gl.glFinish();
	gl.glBindVertexArray(0);
	gl.glUseProgram(0);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "clean");

	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
}

SingleBindingCase::TestSpec SingleBindingCase::genTestSpec (int flags)
{
	const int	datumSize				= 4;
	const int	bufferOffset			= (flags & FLAG_BUF_ALIGNED_OFFSET) ? (32) : (flags & FLAG_BUF_UNALIGNED_OFFSET) ? (19) : (0);
	const int	attrBufAlignment		= ((bufferOffset % datumSize) == 0) ? (0) : (datumSize - (bufferOffset % datumSize));
	const int	positionAttrOffset		= (flags & FLAG_ATTRIB_UNALIGNED) ? (3) : (flags & FLAG_ATTRIB_ALIGNED) ? (attrBufAlignment) : (0);
	const bool	hasColorAttr			= (flags & FLAG_ATTRIBS_SHARED_ELEMS) || (flags & FLAG_ATTRIBS_MULTIPLE_ELEMS);
	const int	colorAttrOffset			= (flags & FLAG_ATTRIBS_SHARED_ELEMS) ? (2 * datumSize) : (flags & FLAG_ATTRIBS_MULTIPLE_ELEMS) ? (4 * datumSize) : (-1);

	const int	bufferStrideBase		= de::max(positionAttrOffset + 4 * datumSize, colorAttrOffset + 4 * datumSize);
	const int	bufferStrideAlignment	= ((bufferStrideBase % datumSize) == 0) ? (0) : (datumSize - (bufferStrideBase % datumSize));
	const int	bufferStridePadding		= ((flags & FLAG_BUF_UNALIGNED_STRIDE) && deIsAligned32(bufferStrideBase, datumSize)) ? (13) : (!(flags & FLAG_BUF_UNALIGNED_STRIDE) && !deIsAligned32(bufferStrideBase, datumSize)) ? (bufferStrideAlignment) : (0);

	TestSpec spec;

	spec.bufferOffset			= bufferOffset;
	spec.bufferStride			= bufferStrideBase + bufferStridePadding;
	spec.positionAttrOffset		= positionAttrOffset;
	spec.colorAttrOffset		= colorAttrOffset;
	spec.hasColorAttr			= hasColorAttr;

	if (flags & FLAG_ATTRIB_UNALIGNED)
		DE_ASSERT(!deIsAligned32(spec.bufferOffset + spec.positionAttrOffset, datumSize));
	else if (flags & FLAG_ATTRIB_ALIGNED)
		DE_ASSERT(deIsAligned32(spec.bufferOffset + spec.positionAttrOffset, datumSize));

	if (flags & FLAG_BUF_UNALIGNED_STRIDE)
		DE_ASSERT(!deIsAligned32(spec.bufferStride, datumSize));
	else
		DE_ASSERT(deIsAligned32(spec.bufferStride, datumSize));

	return spec;
}

std::string SingleBindingCase::genTestDescription (int flags)
{
	std::ostringstream buf;
	buf << "draw test pattern";

	if (flags & FLAG_ATTRIB_UNALIGNED)
		buf << ", attribute offset (unaligned)";
	if (flags & FLAG_ATTRIB_ALIGNED)
		buf << ", attribute offset (aligned)";

	if (flags & FLAG_ATTRIBS_MULTIPLE_ELEMS)
		buf << ", 2 attributes";
	if (flags & FLAG_ATTRIBS_SHARED_ELEMS)
		buf << ", 2 attributes (some components shared)";

	if (flags & FLAG_BUF_ALIGNED_OFFSET)
		buf << ", buffer offset aligned";
	if (flags & FLAG_BUF_UNALIGNED_OFFSET)
		buf << ", buffer offset unaligned";
	if (flags & FLAG_BUF_UNALIGNED_STRIDE)
		buf << ", buffer stride unaligned";

	return buf.str();
}

bool SingleBindingCase::isDataUnaligned (int flags)
{
	if (flags & FLAG_ATTRIB_UNALIGNED)
		return true;
	if (flags & FLAG_ATTRIB_ALIGNED)
		return false;

	return (flags & FLAG_BUF_UNALIGNED_OFFSET) || (flags & FLAG_BUF_UNALIGNED_STRIDE);
}

void SingleBindingCase::createBuffers (void)
{
	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	std::vector<deUint8>	dataBuf	(m_spec.bufferOffset + m_spec.bufferStride * GRID_SIZE * GRID_SIZE * 6);

	// In interleaved mode color rg and position zw are the same. Select "good" values for r and g
	const tcu::Vec4			colorA	(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4			colorB	(0.5f, 1.0f, 0.0f, 1.0f);

	for (int y = 0; y < GRID_SIZE; ++y)
	for (int x = 0; x < GRID_SIZE; ++x)
	{
		const tcu::Vec4&	color = ((x + y) % 2 == 0) ? (colorA) : (colorB);
		const tcu::Vec4		positions[6] =
		{
			tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f),
			tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f),
			tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f),
			tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f),
			tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f),
			tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f),
		};

		// copy cell vertices to the buffer.
		for (int v = 0; v < 6; ++v)
			memcpy(&dataBuf[m_spec.bufferOffset + m_spec.positionAttrOffset + m_spec.bufferStride * ((y * GRID_SIZE + x) * 6 + v)], positions[v].getPtr(), sizeof(positions[v]));

		// copy color to buffer
		if (m_spec.hasColorAttr)
			for (int v = 0; v < 6; ++v)
				memcpy(&dataBuf[m_spec.bufferOffset + m_spec.colorAttrOffset + m_spec.bufferStride * ((y * GRID_SIZE + x) * 6 + v)], color.getPtr(), sizeof(color));
	}

	gl.genBuffers(1, &m_buf);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_buf);
	gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)dataBuf.size(), &dataBuf[0], GL_STATIC_DRAW);
	gl.bindBuffer(GL_ARRAY_BUFFER, 0);

	if (gl.getError() != GL_NO_ERROR)
		throw tcu::TestError("could not init buffer");
}

void SingleBindingCase::createShader (void)
{
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource()) << glu::FragmentSource(s_colorFragmentShader));
	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
		throw tcu::TestError("could not build shader");
}

std::string SingleBindingCase::genVertexSource (void)
{
	const bool			useUniformColor = !m_spec.hasColorAttr;
	std::ostringstream	buf;

	buf <<	"#version 310 es\n"
			"in highp vec4 a_position;\n";

	if (!useUniformColor)
		buf << "in highp vec4 a_color;\n";
	else
		buf << "uniform highp vec4 u_color;\n";

	buf <<	"out highp vec4 v_color;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_color = " << ((useUniformColor) ? ("u_color") : ("a_color")) << ";\n"
			"}\n";

	return buf.str();
}

class MultipleBindingCase : public BindingRenderCase
{
public:

	enum CaseFlag
	{
		FLAG_ZERO_STRIDE		= (1<<0),	// !< set a buffer stride to zero
		FLAG_INSTANCED			= (1<<1),	// !< set a buffer instance divisor to non-zero
		FLAG_ALIASING_BUFFERS	= (1<<2),	// !< bind buffer to multiple binding points
	};

						MultipleBindingCase		(Context& ctx, const char* name, int flags);
						~MultipleBindingCase	(void);

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

private:
	struct TestSpec
	{
		bool zeroStride;
		bool instanced;
		bool aliasingBuffers;
	};

	enum
	{
		GRID_SIZE = 20
	};

	void				renderTo				(tcu::Surface& dst);

	TestSpec			genTestSpec				(int flags) const;
	std::string			genTestDescription		(int flags) const;
	void				createBuffers			(void);
	void				createShader			(void);

	const TestSpec		m_spec;
	glw::GLuint			m_primitiveBuf;
	glw::GLuint			m_colorOffsetBuf;
};

MultipleBindingCase::MultipleBindingCase (Context& ctx, const char* name, int flags)
	: BindingRenderCase	(ctx, name, genTestDescription(flags).c_str(), false)
	, m_spec			(genTestSpec(flags))
	, m_primitiveBuf	(0)
	, m_colorOffsetBuf	(0)
{
	DE_ASSERT(!(m_spec.instanced && m_spec.zeroStride));
}

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

void MultipleBindingCase::init (void)
{
	BindingRenderCase::init();

	// log what we are trying to do

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Rendering " << (int)GRID_SIZE << "x" << (int)GRID_SIZE << " grid.\n"
						<< "Vertex positions:\n"
						<< "	binding point: 1\n"
						<< "Vertex offsets:\n"
						<< "	binding point: 2\n"
						<< "Vertex colors:\n"
						<< "	binding point: 2\n"
						<< "Binding point 1:\n"
						<< "	buffer object: " << m_primitiveBuf << "\n"
						<< "Binding point 2:\n"
						<< "	buffer object: " << ((m_spec.aliasingBuffers) ? (m_primitiveBuf) : (m_colorOffsetBuf)) << "\n"
						<< "	instance divisor: " << ((m_spec.instanced) ? (1) : (0)) << "\n"
						<< "	stride: " << ((m_spec.zeroStride) ? (0) : (4*4*2)) << "\n"
						<< tcu::TestLog::EndMessage;
}

void MultipleBindingCase::deinit (void)
{
	if (m_primitiveBuf)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_primitiveBuf);
		m_primitiveBuf = DE_NULL;
	}

	if (m_colorOffsetBuf)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_colorOffsetBuf);
		m_colorOffsetBuf = DE_NULL;
	}

	BindingRenderCase::deinit();
}

void MultipleBindingCase::renderTo (tcu::Surface& dst)
{
	glu::CallLogWrapper gl					(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	const int			positionLoc			= gl.glGetAttribLocation(m_program->getProgram(), "a_position");
	const int			colorLoc			= gl.glGetAttribLocation(m_program->getProgram(), "a_color");
	const int			offsetLoc			= gl.glGetAttribLocation(m_program->getProgram(), "a_offset");

	const int			positionBinding		= 1;
	const int			colorOffsetBinding	= 2;

	gl.enableLogging(true);

	gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	gl.glClear(GL_COLOR_BUFFER_BIT);
	gl.glViewport(0, 0, dst.getWidth(), dst.getHeight());
	gl.glBindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "set vao");

	gl.glUseProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "use program");

	// Setup format & binding

	gl.glEnableVertexAttribArray(positionLoc);
	gl.glEnableVertexAttribArray(colorLoc);
	gl.glEnableVertexAttribArray(offsetLoc);

	gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, 0);
	gl.glVertexAttribFormat(colorLoc, 4, GL_FLOAT, GL_FALSE, 0);
	gl.glVertexAttribFormat(offsetLoc, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4));

	gl.glVertexAttribBinding(positionLoc, positionBinding);
	gl.glVertexAttribBinding(colorLoc, colorOffsetBinding);
	gl.glVertexAttribBinding(offsetLoc, colorOffsetBinding);

	GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup attribs");

	// setup binding points

	gl.glVertexBindingDivisor(positionBinding, 0);
	gl.glBindVertexBuffer(positionBinding, m_primitiveBuf, 0, sizeof(tcu::Vec4));

	{
		const int			stride	= (m_spec.zeroStride) ? (0) : (2 * (int)sizeof(tcu::Vec4));
		const int			offset	= (!m_spec.aliasingBuffers) ? (0) : (m_spec.instanced) ? (6 * (int)sizeof(tcu::Vec4)) : (6 * GRID_SIZE * GRID_SIZE * (int)sizeof(tcu::Vec4));
		const glw::GLuint	buffer	= (m_spec.aliasingBuffers) ? (m_primitiveBuf) : (m_colorOffsetBuf);
		const int			divisor	= (m_spec.instanced) ? (1) : (0);

		gl.glVertexBindingDivisor(colorOffsetBinding, divisor);
		gl.glBindVertexBuffer(colorOffsetBinding, buffer, offset, (glw::GLsizei)stride);
	}

	GLU_EXPECT_NO_ERROR(gl.glGetError(), "set binding points");

	if (m_spec.instanced)
		gl.glDrawArraysInstanced(GL_TRIANGLES, 0, 6, GRID_SIZE*GRID_SIZE);
	else
		gl.glDrawArrays(GL_TRIANGLES, 0, GRID_SIZE*GRID_SIZE*6);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");

	gl.glFinish();
	gl.glBindVertexArray(0);
	gl.glUseProgram(0);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "clean");

	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
}

MultipleBindingCase::TestSpec MultipleBindingCase::genTestSpec (int flags) const
{
	MultipleBindingCase::TestSpec spec;

	spec.zeroStride			= !!(flags & FLAG_ZERO_STRIDE);
	spec.instanced			= !!(flags & FLAG_INSTANCED);
	spec.aliasingBuffers	= !!(flags & FLAG_ALIASING_BUFFERS);

	return spec;
}

std::string MultipleBindingCase::genTestDescription (int flags) const
{
	std::ostringstream buf;
	buf << "draw test pattern";

	if (flags & FLAG_ZERO_STRIDE)
		buf << ", zero stride";
	if (flags & FLAG_INSTANCED)
		buf << ", instanced binding point";
	if (flags & FLAG_ALIASING_BUFFERS)
		buf << ", binding points share buffer object";

	return buf.str();
}

void MultipleBindingCase::createBuffers (void)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const tcu::Vec4			green				= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4			yellow				= tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);

	const int				vertexDataSize		= (m_spec.instanced) ? (6) : (6 * GRID_SIZE * GRID_SIZE);
	const int				offsetColorSize		= (m_spec.zeroStride) ? (2) : (m_spec.instanced) ? (2 * GRID_SIZE * GRID_SIZE) : (2 * 6 * GRID_SIZE * GRID_SIZE);
	const int				primitiveBufSize	= (m_spec.aliasingBuffers) ? (vertexDataSize + offsetColorSize) : (vertexDataSize);
	const int				colorOffsetBufSize	= (m_spec.aliasingBuffers) ? (0) : (offsetColorSize);

	std::vector<tcu::Vec4>	primitiveData		(primitiveBufSize);
	std::vector<tcu::Vec4>	colorOffsetData		(colorOffsetBufSize);
	tcu::Vec4*				colorOffsetWritePtr = DE_NULL;

	if (m_spec.aliasingBuffers)
	{
		if (m_spec.instanced)
			colorOffsetWritePtr = &primitiveData[6];
		else
			colorOffsetWritePtr = &primitiveData[GRID_SIZE*GRID_SIZE*6];
	}
	else
		colorOffsetWritePtr = &colorOffsetData[0];

	// write vertex position

	if (m_spec.instanced)
	{
		// store single basic primitive
		primitiveData[0] = tcu::Vec4(0.0f,						0.0f,						0.0f, 1.0f);
		primitiveData[1] = tcu::Vec4(0.0f,						2.0f / float(GRID_SIZE),	0.0f, 1.0f);
		primitiveData[2] = tcu::Vec4(2.0f / float(GRID_SIZE),	2.0f / float(GRID_SIZE),	0.0f, 1.0f);
		primitiveData[3] = tcu::Vec4(0.0f,						0.0f,						0.0f, 1.0f);
		primitiveData[4] = tcu::Vec4(2.0f / float(GRID_SIZE),	2.0f / float(GRID_SIZE),	0.0f, 1.0f);
		primitiveData[5] = tcu::Vec4(2.0f / float(GRID_SIZE),	0.0f,						0.0f, 1.0f);
	}
	else
	{
		// store whole grid
		for (int y = 0; y < GRID_SIZE; ++y)
		for (int x = 0; x < GRID_SIZE; ++x)
		{
			primitiveData[(y * GRID_SIZE + x) * 6 + 0] = tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
			primitiveData[(y * GRID_SIZE + x) * 6 + 1] = tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
			primitiveData[(y * GRID_SIZE + x) * 6 + 2] = tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
			primitiveData[(y * GRID_SIZE + x) * 6 + 3] = tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
			primitiveData[(y * GRID_SIZE + x) * 6 + 4] = tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
			primitiveData[(y * GRID_SIZE + x) * 6 + 5] = tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
		}
	}

	// store color&offset

	if (m_spec.zeroStride)
	{
		colorOffsetWritePtr[0] = green;
		colorOffsetWritePtr[1] = tcu::Vec4(0.0f);
	}
	else if (m_spec.instanced)
	{
		for (int y = 0; y < GRID_SIZE; ++y)
		for (int x = 0; x < GRID_SIZE; ++x)
		{
			const tcu::Vec4& color = ((x + y) % 2 == 0) ? (green) : (yellow);

			colorOffsetWritePtr[(y * GRID_SIZE + x) * 2 + 0] = color;
			colorOffsetWritePtr[(y * GRID_SIZE + x) * 2 + 1] = tcu::Vec4(float(x) / float(GRID_SIZE) * 2.0f - 1.0f, float(y) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 0.0f);
		}
	}
	else
	{
		for (int y = 0; y < GRID_SIZE; ++y)
		for (int x = 0; x < GRID_SIZE; ++x)
		for (int v = 0; v < 6; ++v)
		{
			const tcu::Vec4& color = ((x + y) % 2 == 0) ? (green) : (yellow);

			colorOffsetWritePtr[((y * GRID_SIZE + x) * 6 + v) * 2 + 0] = color;
			colorOffsetWritePtr[((y * GRID_SIZE + x) * 6 + v) * 2 + 1] = tcu::Vec4(0.0f);
		}
	}

	// upload vertex data

	gl.genBuffers(1, &m_primitiveBuf);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_primitiveBuf);
	gl.bufferData(GL_ARRAY_BUFFER, (int)(primitiveData.size() * sizeof(tcu::Vec4)), primitiveData[0].getPtr(), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "upload data");

	if (!m_spec.aliasingBuffers)
	{
		// upload color & offset data

		gl.genBuffers(1, &m_colorOffsetBuf);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_colorOffsetBuf);
		gl.bufferData(GL_ARRAY_BUFFER, (int)(colorOffsetData.size() * sizeof(tcu::Vec4)), colorOffsetData[0].getPtr(), GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "upload colordata");
	}
}

void MultipleBindingCase::createShader (void)
{
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_positionColorOffsetShader) << glu::FragmentSource(s_colorFragmentShader));
	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
		throw tcu::TestError("could not build shader");
}

class MixedBindingCase : public BindingRenderCase
{
public:

	enum CaseType
	{
		CASE_BASIC = 0,
		CASE_INSTANCED_BINDING,
		CASE_INSTANCED_ATTRIB,

		CASE_LAST
	};

						MixedBindingCase		(Context& ctx, const char* name, const char* desc, CaseType caseType);
						~MixedBindingCase		(void);

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

private:
	enum
	{
		GRID_SIZE = 20
	};

	void				renderTo				(tcu::Surface& dst);
	void				createBuffers			(void);
	void				createShader			(void);

	const CaseType		m_case;
	glw::GLuint			m_posBuffer;
	glw::GLuint			m_colorOffsetBuffer;
};

MixedBindingCase::MixedBindingCase (Context& ctx, const char* name, const char* desc, CaseType caseType)
	: BindingRenderCase		(ctx, name, desc, false)
	, m_case				(caseType)
	, m_posBuffer			(0)
	, m_colorOffsetBuffer	(0)
{
	DE_ASSERT(caseType < CASE_LAST);
}

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

void MixedBindingCase::init (void)
{
	BindingRenderCase::init();
}

void MixedBindingCase::deinit (void)
{
	if (m_posBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_posBuffer);
		m_posBuffer = DE_NULL;
	}

	if (m_colorOffsetBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_colorOffsetBuffer);
		m_colorOffsetBuffer = DE_NULL;
	}

	BindingRenderCase::deinit();
}

void MixedBindingCase::renderTo (tcu::Surface& dst)
{
	glu::CallLogWrapper gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	const int			positionLoc		= gl.glGetAttribLocation(m_program->getProgram(), "a_position");
	const int			colorLoc		= gl.glGetAttribLocation(m_program->getProgram(), "a_color");
	const int			offsetLoc		= gl.glGetAttribLocation(m_program->getProgram(), "a_offset");

	gl.enableLogging(true);

	gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	gl.glClear(GL_COLOR_BUFFER_BIT);
	gl.glViewport(0, 0, dst.getWidth(), dst.getHeight());
	gl.glBindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "set vao");

	gl.glUseProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "use program");

	switch (m_case)
	{
		case CASE_BASIC:
		{
			// bind position using vertex_attrib_binding api

			gl.glBindVertexBuffer(positionLoc, m_posBuffer, 0, (glw::GLsizei)sizeof(tcu::Vec4));
			gl.glVertexAttribBinding(positionLoc, positionLoc);
			gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, 0);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "set binding");

			// bind color using old api

			gl.glBindBuffer(GL_ARRAY_BUFFER, m_colorOffsetBuffer);
			gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, glw::GLsizei(2 * sizeof(tcu::Vec4)), DE_NULL);
			gl.glVertexAttribPointer(offsetLoc, 4, GL_FLOAT, GL_FALSE, glw::GLsizei(2 * sizeof(tcu::Vec4)), glu::BufferOffsetAsPointer(sizeof(tcu::Vec4)));
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "set va");

			// draw
			gl.glEnableVertexAttribArray(positionLoc);
			gl.glEnableVertexAttribArray(colorLoc);
			gl.glEnableVertexAttribArray(offsetLoc);
			gl.glDrawArrays(GL_TRIANGLES, 0, 6*GRID_SIZE*GRID_SIZE);
			break;
		}

		case CASE_INSTANCED_BINDING:
		{
			// bind position using old api
			gl.glBindBuffer(GL_ARRAY_BUFFER, m_posBuffer);
			gl.glVertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "set va");

			// bind color using vertex_attrib_binding api
			gl.glBindVertexBuffer(colorLoc, m_colorOffsetBuffer, 0, (glw::GLsizei)(2 * sizeof(tcu::Vec4)));
			gl.glVertexBindingDivisor(colorLoc, 1);

			gl.glVertexAttribBinding(colorLoc, colorLoc);
			gl.glVertexAttribBinding(offsetLoc, colorLoc);

			gl.glVertexAttribFormat(colorLoc, 4, GL_FLOAT, GL_FALSE, 0);
			gl.glVertexAttribFormat(offsetLoc, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4));

			GLU_EXPECT_NO_ERROR(gl.glGetError(), "set binding");

			// draw
			gl.glEnableVertexAttribArray(positionLoc);
			gl.glEnableVertexAttribArray(colorLoc);
			gl.glEnableVertexAttribArray(offsetLoc);
			gl.glDrawArraysInstanced(GL_TRIANGLES, 0, 6, GRID_SIZE*GRID_SIZE);
			break;
		}

		case CASE_INSTANCED_ATTRIB:
		{
			// bind position using vertex_attrib_binding api
			gl.glBindVertexBuffer(positionLoc, m_posBuffer, 0, (glw::GLsizei)sizeof(tcu::Vec4));
			gl.glVertexAttribBinding(positionLoc, positionLoc);
			gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, 0);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "set binding");

			// bind color using old api
			gl.glBindBuffer(GL_ARRAY_BUFFER, m_colorOffsetBuffer);
			gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, glw::GLsizei(2 * sizeof(tcu::Vec4)), DE_NULL);
			gl.glVertexAttribPointer(offsetLoc, 4, GL_FLOAT, GL_FALSE, glw::GLsizei(2 * sizeof(tcu::Vec4)), glu::BufferOffsetAsPointer(sizeof(tcu::Vec4)));
			gl.glVertexAttribDivisor(colorLoc, 1);
			gl.glVertexAttribDivisor(offsetLoc, 1);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "set va");

			// draw
			gl.glEnableVertexAttribArray(positionLoc);
			gl.glEnableVertexAttribArray(colorLoc);
			gl.glEnableVertexAttribArray(offsetLoc);
			gl.glDrawArraysInstanced(GL_TRIANGLES, 0, 6, GRID_SIZE*GRID_SIZE);
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
	}

	gl.glFinish();
	gl.glBindVertexArray(0);
	gl.glUseProgram(0);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "clean");

	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
}

void MixedBindingCase::createBuffers (void)
{
	const glw::Functions&	gl								= m_context.getRenderContext().getFunctions();
	const tcu::Vec4			green							= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4			yellow							= tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);

	// draw grid. In instanced mode, each cell is an instance
	const bool				instanced						= (m_case == CASE_INSTANCED_BINDING) || (m_case == CASE_INSTANCED_ATTRIB);
	const int				numCells						= GRID_SIZE*GRID_SIZE;
	const int				numPositionCells				= (instanced) ? (1) : (numCells);
	const int				numPositionElements				= 6 * numPositionCells;
	const int				numInstanceElementsPerCell		= (instanced) ? (1) : (6);
	const int				numColorOffsetElements			= numInstanceElementsPerCell * numCells;

	std::vector<tcu::Vec4>	positionData					(numPositionElements);
	std::vector<tcu::Vec4>	colorOffsetData					(2 * numColorOffsetElements);

	// positions

	for (int primNdx = 0; primNdx < numPositionCells; ++primNdx)
	{
		positionData[primNdx*6 + 0] =  tcu::Vec4(0.0f,						0.0f,						0.0f, 1.0f);
		positionData[primNdx*6 + 1] =  tcu::Vec4(0.0f,						2.0f / float(GRID_SIZE),	0.0f, 1.0f);
		positionData[primNdx*6 + 2] =  tcu::Vec4(2.0f / float(GRID_SIZE),	2.0f / float(GRID_SIZE),	0.0f, 1.0f);
		positionData[primNdx*6 + 3] =  tcu::Vec4(0.0f,						0.0f,						0.0f, 1.0f);
		positionData[primNdx*6 + 4] =  tcu::Vec4(2.0f / float(GRID_SIZE),	2.0f / float(GRID_SIZE),	0.0f, 1.0f);
		positionData[primNdx*6 + 5] =  tcu::Vec4(2.0f / float(GRID_SIZE),	0.0f,						0.0f, 1.0f);
	}

	// color & offset

	for (int y = 0; y < GRID_SIZE; ++y)
	for (int x = 0; x < GRID_SIZE; ++x)
	{
		for (int v = 0; v < numInstanceElementsPerCell; ++v)
		{
			const tcu::Vec4& color = ((x + y) % 2 == 0) ? (green) : (yellow);

			colorOffsetData[((y * GRID_SIZE + x) * numInstanceElementsPerCell + v) * 2 + 0] = color;
			colorOffsetData[((y * GRID_SIZE + x) * numInstanceElementsPerCell + v) * 2 + 1] = tcu::Vec4(float(x) / float(GRID_SIZE) * 2.0f - 1.0f, float(y) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 0.0f);
		}
	}

	// upload vertex data

	gl.genBuffers(1, &m_posBuffer);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_posBuffer);
	gl.bufferData(GL_ARRAY_BUFFER, (int)(positionData.size() * sizeof(tcu::Vec4)), positionData[0].getPtr(), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "upload position data");

	gl.genBuffers(1, &m_colorOffsetBuffer);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_colorOffsetBuffer);
	gl.bufferData(GL_ARRAY_BUFFER, (int)(colorOffsetData.size() * sizeof(tcu::Vec4)), colorOffsetData[0].getPtr(), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "upload position data");
}

void MixedBindingCase::createShader (void)
{
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_positionColorOffsetShader) << glu::FragmentSource(s_colorFragmentShader));
	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
		throw tcu::TestError("could not build shader");
}

class MixedApiCase : public BindingRenderCase
{
public:

	enum CaseType
	{
		CASE_CHANGE_BUFFER = 0,
		CASE_CHANGE_BUFFER_OFFSET,
		CASE_CHANGE_BUFFER_STRIDE,
		CASE_CHANGE_BINDING_POINT,

		CASE_LAST
	};

						MixedApiCase			(Context& ctx, const char* name, const char* desc, CaseType caseType);
						~MixedApiCase			(void);

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

private:
	enum
	{
		GRID_SIZE = 20
	};

	void				renderTo				(tcu::Surface& dst);
	void				createBuffers			(void);
	void				createShader			(void);

	const CaseType		m_case;
	glw::GLuint			m_buffer;
};


MixedApiCase::MixedApiCase (Context& ctx, const char* name, const char* desc, CaseType caseType)
	: BindingRenderCase		(ctx, name, desc, false)
	, m_case				(caseType)
	, m_buffer				(0)
{
	DE_ASSERT(caseType < CASE_LAST);
}

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

void MixedApiCase::init (void)
{
	BindingRenderCase::init();
}

void MixedApiCase::deinit (void)
{
	if (m_buffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffer);
		m_buffer = DE_NULL;
	}

	BindingRenderCase::deinit();
}

void MixedApiCase::renderTo (tcu::Surface& dst)
{
	glu::CallLogWrapper		gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	const int				positionLoc		= gl.glGetAttribLocation(m_program->getProgram(), "a_position");
	const int				colorLoc		= gl.glGetAttribLocation(m_program->getProgram(), "a_color");
	glu::Buffer				unusedBuffer	(m_context.getRenderContext());

	gl.enableLogging(true);

	gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	gl.glClear(GL_COLOR_BUFFER_BIT);
	gl.glViewport(0, 0, dst.getWidth(), dst.getHeight());
	gl.glBindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "set vao");

	gl.glUseProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "use program");

	switch (m_case)
	{
		case CASE_CHANGE_BUFFER:
		{
			// bind data using old api

			gl.glBindBuffer(GL_ARRAY_BUFFER, *unusedBuffer);
			gl.glVertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), (const deUint8*)DE_NULL);
			gl.glVertexAttribPointer(colorLoc,    4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), glu::BufferOffsetAsPointer(sizeof(tcu::Vec4)));

			// change buffer with vertex_attrib_binding

			gl.glBindVertexBuffer(positionLoc, m_buffer, 0,                 (glw::GLsizei)(2 * sizeof(tcu::Vec4)));
			gl.glBindVertexBuffer(colorLoc,    m_buffer, sizeof(tcu::Vec4), (glw::GLsizei)(2 * sizeof(tcu::Vec4)));

			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");
			break;
		}

		case CASE_CHANGE_BUFFER_OFFSET:
		{
			// bind data using old api

			gl.glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
			gl.glVertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), (const deUint8*)DE_NULL);
			gl.glVertexAttribPointer(colorLoc,    4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), (const deUint8*)DE_NULL);

			// change buffer offset with vertex_attrib_binding

			gl.glBindVertexBuffer(positionLoc, m_buffer, 0,                 (glw::GLsizei)(2 * sizeof(tcu::Vec4)));
			gl.glBindVertexBuffer(colorLoc,    m_buffer, sizeof(tcu::Vec4), (glw::GLsizei)(2 * sizeof(tcu::Vec4)));

			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");
			break;
		}

		case CASE_CHANGE_BUFFER_STRIDE:
		{
			// bind data using old api

			gl.glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
			gl.glVertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 8, (const deUint8*)DE_NULL);
			gl.glVertexAttribPointer(colorLoc,    4, GL_FLOAT, GL_FALSE, 4, (const deUint8*)DE_NULL);

			// change buffer stride with vertex_attrib_binding

			gl.glBindVertexBuffer(positionLoc, m_buffer, 0,                 (glw::GLsizei)(2 * sizeof(tcu::Vec4)));
			gl.glBindVertexBuffer(colorLoc,    m_buffer, sizeof(tcu::Vec4), (glw::GLsizei)(2 * sizeof(tcu::Vec4)));

			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");
			break;
		}

		case CASE_CHANGE_BINDING_POINT:
		{
			const int maxUsedLocation	= de::max(positionLoc, colorLoc);
			const int bindingPoint1		= maxUsedLocation + 1;
			const int bindingPoint2		= maxUsedLocation + 2;

			// bind data using old api

			gl.glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
			gl.glVertexAttribPointer(bindingPoint1, 4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), (const deUint8*)DE_NULL);
			gl.glVertexAttribPointer(bindingPoint2, 4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), glu::BufferOffsetAsPointer(sizeof(tcu::Vec4)));

			// change buffer binding point with vertex_attrib_binding

			gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, 0);
			gl.glVertexAttribFormat(colorLoc, 4, GL_FLOAT, GL_FALSE, 0);

			gl.glVertexAttribBinding(positionLoc, bindingPoint1);
			gl.glVertexAttribBinding(colorLoc, bindingPoint2);

			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
	}

	// draw
	gl.glEnableVertexAttribArray(positionLoc);
	gl.glEnableVertexAttribArray(colorLoc);
	gl.glDrawArrays(GL_TRIANGLES, 0, 6*GRID_SIZE*GRID_SIZE);

	gl.glFinish();
	gl.glBindVertexArray(0);
	gl.glUseProgram(0);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "clean");

	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
}

void MixedApiCase::createBuffers (void)
{
	const tcu::Vec4			green							= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4			yellow							= tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);

	const glw::Functions&	gl								= m_context.getRenderContext().getFunctions();
	std::vector<tcu::Vec4>	vertexData						(12 * GRID_SIZE * GRID_SIZE);

	for (int y = 0; y < GRID_SIZE; ++y)
	for (int x = 0; x < GRID_SIZE; ++x)
	{
		const tcu::Vec4& color = ((x + y) % 2 == 0) ? (green) : (yellow);

		vertexData[(y * GRID_SIZE + x) * 12 +  0] = tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
		vertexData[(y * GRID_SIZE + x) * 12 +  1] = color;
		vertexData[(y * GRID_SIZE + x) * 12 +  2] = tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
		vertexData[(y * GRID_SIZE + x) * 12 +  3] = color;
		vertexData[(y * GRID_SIZE + x) * 12 +  4] = tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
		vertexData[(y * GRID_SIZE + x) * 12 +  5] = color;
		vertexData[(y * GRID_SIZE + x) * 12 +  6] = tcu::Vec4(float(x+0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
		vertexData[(y * GRID_SIZE + x) * 12 +  7] = color;
		vertexData[(y * GRID_SIZE + x) * 12 +  8] = tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+1) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
		vertexData[(y * GRID_SIZE + x) * 12 +  9] = color;
		vertexData[(y * GRID_SIZE + x) * 12 + 10] = tcu::Vec4(float(x+1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y+0) / float(GRID_SIZE) * 2.0f - 1.0f, 0.0f, 1.0f);
		vertexData[(y * GRID_SIZE + x) * 12 + 11] = color;
	}

	// upload vertex data

	gl.genBuffers(1, &m_buffer);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer);
	gl.bufferData(GL_ARRAY_BUFFER, (int)(vertexData.size() * sizeof(tcu::Vec4)), vertexData[0].getPtr(), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "upload data");
}

void MixedApiCase::createShader (void)
{
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_positionColorShader) << glu::FragmentSource(s_colorFragmentShader));
	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
		throw tcu::TestError("could not build shader");
}

class DefaultVAOCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_BIND_VERTEX_BUFFER,
		CASE_VERTEX_ATTRIB_FORMAT,
		CASE_VERTEX_ATTRIB_I_FORMAT,
		CASE_VERTEX_ATTRIB_BINDING,
		CASE_VERTEX_BINDING_DIVISOR,

		CASE_LAST
	};

					DefaultVAOCase		(Context& ctx, const char* name, const char* desc, CaseType caseType);
					~DefaultVAOCase		(void);

	IterateResult	iterate				(void);

private:
	const CaseType	m_caseType;
};

DefaultVAOCase::DefaultVAOCase (Context& ctx, const char* name, const char* desc, CaseType caseType)
	: TestCase		(ctx, name, desc)
	, m_caseType	(caseType)
{
	DE_ASSERT(caseType < CASE_LAST);
}

DefaultVAOCase::~DefaultVAOCase (void)
{
}

DefaultVAOCase::IterateResult DefaultVAOCase::iterate (void)
{
	glw::GLenum			error	= 0;
	glu::CallLogWrapper gl		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());

	gl.enableLogging(true);

	switch (m_caseType)
	{
		case CASE_BIND_VERTEX_BUFFER:
		{
			glu::Buffer buffer(m_context.getRenderContext());
			gl.glBindVertexBuffer(0, *buffer, 0, 0);
			break;
		}

		case CASE_VERTEX_ATTRIB_FORMAT:
			gl.glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
			break;

		case CASE_VERTEX_ATTRIB_I_FORMAT:
			gl.glVertexAttribIFormat(0, 4, GL_INT, 0);
			break;

		case CASE_VERTEX_ATTRIB_BINDING:
			gl.glVertexAttribBinding(0, 0);
			break;

		case CASE_VERTEX_BINDING_DIVISOR:
			gl.glVertexBindingDivisor(0, 1);
			break;

		default:
			DE_ASSERT(false);
	}

	error = gl.glGetError();

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

	return STOP;
}

class BindToCreateCase : public TestCase
{
public:
					BindToCreateCase	(Context& ctx, const char* name, const char* desc);
					~BindToCreateCase	(void);

	IterateResult	iterate				(void);
};

BindToCreateCase::BindToCreateCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

BindToCreateCase::~BindToCreateCase (void)
{
}

BindToCreateCase::IterateResult BindToCreateCase::iterate (void)
{
	glw::GLuint			buffer	= 0;
	glw::GLenum			error;
	glu::CallLogWrapper gl		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	glu::VertexArray	vao		(m_context.getRenderContext());

	gl.enableLogging(true);

	gl.glGenBuffers(1, &buffer);
	gl.glDeleteBuffers(1, &buffer);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "");

	gl.glBindVertexArray(*vao);
	gl.glBindVertexBuffer(0, buffer, 0, 0);

	error = gl.glGetError();

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

	return STOP;
}

class NegativeApiCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_LARGE_OFFSET,
		CASE_LARGE_STRIDE,
		CASE_NEGATIVE_STRIDE,
		CASE_NEGATIVE_OFFSET,
		CASE_INVALID_ATTR,
		CASE_INVALID_BINDING,

		CASE_LAST
	};
					NegativeApiCase		(Context& ctx, const char* name, const char* desc, CaseType caseType);
					~NegativeApiCase	(void);

	IterateResult	iterate				(void);

private:
	const CaseType	m_caseType;
};

NegativeApiCase::NegativeApiCase (Context& ctx, const char* name, const char* desc, CaseType caseType)
	: TestCase		(ctx, name, desc)
	, m_caseType	(caseType)
{
}

NegativeApiCase::~NegativeApiCase (void)
{
}

NegativeApiCase::IterateResult NegativeApiCase::iterate (void)
{
	glw::GLenum			error;
	glu::CallLogWrapper gl		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	glu::VertexArray	vao		(m_context.getRenderContext());

	gl.enableLogging(true);
	gl.glBindVertexArray(*vao);

	switch (m_caseType)
	{
		case CASE_LARGE_OFFSET:
		{
			glw::GLint	maxOffset	= -1;
			glw::GLint	largeOffset;

			gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &maxOffset);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");

			largeOffset = maxOffset + 1;

			// skip if maximum unsigned or signed values
			if (maxOffset == -1 || maxOffset == 0x7FFFFFFF)
				throw tcu::NotSupportedError("Implementation supports all offsets");

			gl.glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, largeOffset);
			break;
		}

		case CASE_LARGE_STRIDE:
		{
			glu::Buffer buffer		(m_context.getRenderContext());
			glw::GLint	maxStride	= -1;
			glw::GLint	largeStride;

			gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");

			largeStride = maxStride + 1;

			// skip if maximum unsigned or signed values
			if (maxStride == -1 || maxStride == 0x7FFFFFFF)
				throw tcu::NotSupportedError("Implementation supports all strides");

			gl.glBindVertexBuffer(0, *buffer, 0, largeStride);
			break;
		}

		case CASE_NEGATIVE_STRIDE:
		{
			glu::Buffer buffer(m_context.getRenderContext());
			gl.glBindVertexBuffer(0, *buffer, 0, -20);
			break;
		}

		case CASE_NEGATIVE_OFFSET:
		{
			glu::Buffer buffer(m_context.getRenderContext());
			gl.glBindVertexBuffer(0, *buffer, -20, 0);
			break;
		}

		case CASE_INVALID_ATTR:
		{
			glw::GLint maxIndex = -1;
			glw::GLint largeIndex;

			gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxIndex);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");

			largeIndex = maxIndex + 1;

			// skip if maximum unsigned or signed values
			if (maxIndex == -1 || maxIndex == 0x7FFFFFFF)
				throw tcu::NotSupportedError("Implementation supports any attribute index");

			gl.glVertexAttribBinding(largeIndex, 0);
			break;
		}

		case CASE_INVALID_BINDING:
		{
			glw::GLint maxBindings = -1;
			glw::GLint largeBinding;

			gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &maxBindings);
			GLU_EXPECT_NO_ERROR(gl.glGetError(), "");

			largeBinding = maxBindings + 1;

			// skip if maximum unsigned or signed values
			if (maxBindings == -1 || maxBindings == 0x7FFFFFFF)
				throw tcu::NotSupportedError("Implementation supports any binding");

			gl.glVertexAttribBinding(0, largeBinding);
			break;
		}

		default:
			DE_ASSERT(false);
	}

	error = gl.glGetError();

	if (error != GL_INVALID_VALUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Expected GL_INVALID_VALUE, got " << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid error");
	}
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	return STOP;
}

} // anonymous

VertexAttributeBindingTests::VertexAttributeBindingTests (Context& context)
	: TestCaseGroup(context, "vertex_attribute_binding", "Test vertex attribute binding")
{
}

VertexAttributeBindingTests::~VertexAttributeBindingTests (void)
{
}

void VertexAttributeBindingTests::init (void)
{
	tcu::TestCaseGroup* const usageGroup	= new tcu::TestCaseGroup(m_testCtx, "usage", "Test using binding points");
	tcu::TestCaseGroup* const negativeGroup	= new tcu::TestCaseGroup(m_testCtx, "negative", "Negative test");

	addChild(usageGroup);
	addChild(negativeGroup);

	// .usage
	{
		tcu::TestCaseGroup* const singleGroup	= new tcu::TestCaseGroup(m_testCtx, "single_binding", "Test using single binding point");
		tcu::TestCaseGroup* const multipleGroup	= new tcu::TestCaseGroup(m_testCtx, "multiple_bindings", "Test using multiple binding points");
		tcu::TestCaseGroup* const mixedGroup	= new tcu::TestCaseGroup(m_testCtx, "mixed_usage", "Test using binding point and non binding point api variants");

		usageGroup->addChild(singleGroup);
		usageGroup->addChild(multipleGroup);
		usageGroup->addChild(mixedGroup);

		// single binding

		singleGroup->addChild(new SingleBindingCase(m_context, "elements_1",																					  0));
		singleGroup->addChild(new SingleBindingCase(m_context, "elements_2",																					  SingleBindingCase::FLAG_ATTRIBS_MULTIPLE_ELEMS));
		singleGroup->addChild(new SingleBindingCase(m_context, "elements_2_share_elements",																		  SingleBindingCase::FLAG_ATTRIBS_SHARED_ELEMS));
		singleGroup->addChild(new SingleBindingCase(m_context, "offset_elements_1",								SingleBindingCase::FLAG_BUF_ALIGNED_OFFSET		| 0));
		singleGroup->addChild(new SingleBindingCase(m_context, "offset_elements_2",								SingleBindingCase::FLAG_BUF_ALIGNED_OFFSET		| SingleBindingCase::FLAG_ATTRIBS_MULTIPLE_ELEMS));
		singleGroup->addChild(new SingleBindingCase(m_context, "offset_elements_2_share_elements",				SingleBindingCase::FLAG_BUF_ALIGNED_OFFSET		| SingleBindingCase::FLAG_ATTRIBS_SHARED_ELEMS));
		singleGroup->addChild(new SingleBindingCase(m_context, "unaligned_offset_elements_1_aligned_elements",	SingleBindingCase::FLAG_BUF_UNALIGNED_OFFSET	| SingleBindingCase::FLAG_ATTRIB_ALIGNED));			// !< total offset is aligned

		// multiple bindings

		multipleGroup->addChild(new MultipleBindingCase(m_context, "basic",									0));
		multipleGroup->addChild(new MultipleBindingCase(m_context, "zero_stride",							MultipleBindingCase::FLAG_ZERO_STRIDE));
		multipleGroup->addChild(new MultipleBindingCase(m_context, "instanced",								MultipleBindingCase::FLAG_INSTANCED));
		multipleGroup->addChild(new MultipleBindingCase(m_context, "aliasing_buffer_zero_stride",			MultipleBindingCase::FLAG_ALIASING_BUFFERS	| MultipleBindingCase::FLAG_ZERO_STRIDE));
		multipleGroup->addChild(new MultipleBindingCase(m_context, "aliasing_buffer_instanced",				MultipleBindingCase::FLAG_ALIASING_BUFFERS	| MultipleBindingCase::FLAG_INSTANCED));

		// mixed cases
		mixedGroup->addChild(new MixedBindingCase(m_context,		"mixed_attribs_basic",					"Use different api for different attributes",			MixedBindingCase::CASE_BASIC));
		mixedGroup->addChild(new MixedBindingCase(m_context,		"mixed_attribs_instanced_binding",		"Use different api for different attributes",			MixedBindingCase::CASE_INSTANCED_BINDING));
		mixedGroup->addChild(new MixedBindingCase(m_context,		"mixed_attribs_instanced_attrib",		"Use different api for different attributes",			MixedBindingCase::CASE_INSTANCED_ATTRIB));

		mixedGroup->addChild(new MixedApiCase(m_context,			"mixed_api_change_buffer",				"change buffer with vertex_attrib_binding api",			MixedApiCase::CASE_CHANGE_BUFFER));
		mixedGroup->addChild(new MixedApiCase(m_context,			"mixed_api_change_buffer_offset",		"change buffer offset with vertex_attrib_binding api",	MixedApiCase::CASE_CHANGE_BUFFER_OFFSET));
		mixedGroup->addChild(new MixedApiCase(m_context,			"mixed_api_change_buffer_stride",		"change buffer stride with vertex_attrib_binding api",	MixedApiCase::CASE_CHANGE_BUFFER_STRIDE));
		mixedGroup->addChild(new MixedApiCase(m_context,			"mixed_api_change_binding_point",		"change binding point with vertex_attrib_binding api",	MixedApiCase::CASE_CHANGE_BINDING_POINT));
	}

	// negative
	{
		negativeGroup->addChild(new DefaultVAOCase(m_context,	"default_vao_bind_vertex_buffer",			"use with default vao",	DefaultVAOCase::CASE_BIND_VERTEX_BUFFER));
		negativeGroup->addChild(new DefaultVAOCase(m_context,	"default_vao_vertex_attrib_format",			"use with default vao",	DefaultVAOCase::CASE_VERTEX_ATTRIB_FORMAT));
		negativeGroup->addChild(new DefaultVAOCase(m_context,	"default_vao_vertex_attrib_i_format",		"use with default vao",	DefaultVAOCase::CASE_VERTEX_ATTRIB_I_FORMAT));
		negativeGroup->addChild(new DefaultVAOCase(m_context,	"default_vao_vertex_attrib_binding",		"use with default vao",	DefaultVAOCase::CASE_VERTEX_ATTRIB_BINDING));
		negativeGroup->addChild(new DefaultVAOCase(m_context,	"default_vao_vertex_binding_divisor",		"use with default vao",	DefaultVAOCase::CASE_VERTEX_BINDING_DIVISOR));

		negativeGroup->addChild(new BindToCreateCase(m_context,	"bind_create_new_buffer",					"bind not existing buffer"));

		negativeGroup->addChild(new NegativeApiCase(m_context, "vertex_attrib_format_large_offset",			"large relative offset",	NegativeApiCase::CASE_LARGE_OFFSET));
		negativeGroup->addChild(new NegativeApiCase(m_context, "bind_vertex_buffer_large_stride",			"large stride",				NegativeApiCase::CASE_LARGE_STRIDE));
		negativeGroup->addChild(new NegativeApiCase(m_context, "bind_vertex_buffer_negative_stride",		"negative stride",			NegativeApiCase::CASE_NEGATIVE_STRIDE));
		negativeGroup->addChild(new NegativeApiCase(m_context, "bind_vertex_buffer_negative_offset",		"negative offset",			NegativeApiCase::CASE_NEGATIVE_OFFSET));
		negativeGroup->addChild(new NegativeApiCase(m_context, "vertex_attrib_binding_invalid_attr",		"bind invalid attr",		NegativeApiCase::CASE_INVALID_ATTR));
		negativeGroup->addChild(new NegativeApiCase(m_context, "vertex_attrib_binding_invalid_binding",		"bind invalid binding",		NegativeApiCase::CASE_INVALID_BINDING));
	}
}

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