/*-------------------------------------------------------------------------
 * 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 Negative Vertex Array API tests.
 *//*--------------------------------------------------------------------*/

#include "es31fNegativeVertexArrayApiTests.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluContextInfo.hpp"
#include "gluShaderProgram.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"
#include "tcuStringTemplate.hpp"

namespace deqp
{

using std::string;
using std::map;

namespace gles31
{
namespace Functional
{
namespace NegativeTestShared
{

using tcu::TestLog;
using glu::CallLogWrapper;
using namespace glw;

static const char* vertexShaderSource		=	"${GLSL_VERSION_STRING}\n"
												"void main (void)\n"
												"{\n"
												"	gl_Position = vec4(0.0);\n"
												"}\n\0";

static const char* fragmentShaderSource		=	"${GLSL_VERSION_STRING}\n"
												"layout(location = 0) out mediump vec4 fragColor;"
												"void main (void)\n"
												"{\n"
												"	fragColor = vec4(0.0);\n"
												"}\n\0";

static const char* geometryShaderSource		=	"#version 320 es\n"
												"layout(points) in;\n"
												"layout(points, max_vertices = 3) out;\n"
												"void main (void)\n"
												"{\n"
												"}\n";

void vertex_attribf (NegativeTestContext& ctx)
{
	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	ctx.glVertexAttrib1f(maxVertexAttribs, 0.0f);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttrib2f(maxVertexAttribs, 0.0f, 0.0f);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttrib3f(maxVertexAttribs, 0.0f, 0.0f, 0.0f);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttrib4f(maxVertexAttribs, 0.0f, 0.0f, 0.0f, 0.0f);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void vertex_attribfv (NegativeTestContext& ctx)
{
	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	float v[4] = {0.0f};
	ctx.glVertexAttrib1fv(maxVertexAttribs, &v[0]);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttrib2fv(maxVertexAttribs, &v[0]);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttrib3fv(maxVertexAttribs, &v[0]);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttrib4fv(maxVertexAttribs, &v[0]);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void vertex_attribi4 (NegativeTestContext& ctx)
{
	int maxVertexAttribs	= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	GLint valInt			= 0;
	GLuint valUint			= 0;

	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	ctx.glVertexAttribI4i(maxVertexAttribs, valInt, valInt, valInt, valInt);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttribI4ui(maxVertexAttribs, valUint, valUint, valUint, valUint);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void vertex_attribi4v (NegativeTestContext& ctx)
{
	int maxVertexAttribs	= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	GLint valInt[4]			= { 0 };
	GLuint valUint[4]		= { 0 };

	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	ctx.glVertexAttribI4iv(maxVertexAttribs, &valInt[0]);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glVertexAttribI4uiv(maxVertexAttribs, &valUint[0]);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void vertex_attrib_pointer (NegativeTestContext& ctx)
{
	ctx.beginSection("GL_INVALID_ENUM is generated if type is not an accepted value.");
	ctx.glVertexAttribPointer(0, 1, 0, GL_TRUE, 0, 0);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	ctx.glVertexAttribPointer(maxVertexAttribs, 1, GL_BYTE, GL_TRUE, 0, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if size is not 1, 2, 3, or 4.");
	ctx.glVertexAttribPointer(0, 0, GL_BYTE, GL_TRUE, 0, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if stride is negative.");
	ctx.glVertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, -1, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_OPERATION is generated if type is GL_INT_2_10_10_10_REV or GL_UNSIGNED_INT_2_10_10_10_REV and size is not 4.");
	ctx.glVertexAttribPointer(0, 2, GL_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.glVertexAttribPointer(0, 2, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.glVertexAttribPointer(0, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
	ctx.expectError(GL_NO_ERROR);
	ctx.glVertexAttribPointer(0, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0, 0);
	ctx.expectError(GL_NO_ERROR);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_OPERATION is generated a non-zero vertex array object is bound, zero is bound to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.");
	GLuint vao = 0;
	GLbyte offset = 1;
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.expectError(GL_NO_ERROR);

	ctx.glVertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, &offset);
	ctx.expectError(GL_INVALID_OPERATION);

	ctx.glBindVertexArray(0);
	ctx.glDeleteVertexArrays(1, &vao);
	ctx.expectError(GL_NO_ERROR);
	ctx.endSection();
}

void vertex_attrib_i_pointer (NegativeTestContext& ctx)
{
	ctx.beginSection("GL_INVALID_ENUM is generated if type is not an accepted value.");
	ctx.glVertexAttribIPointer(0, 1, 0, 0, 0);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glVertexAttribIPointer(0, 4, GL_INT_2_10_10_10_REV, 0, 0);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glVertexAttribIPointer(0, 4, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 0);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	ctx.glVertexAttribIPointer(maxVertexAttribs, 1, GL_BYTE, 0, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if size is not 1, 2, 3, or 4.");
	ctx.glVertexAttribIPointer(0, 0, GL_BYTE, 0, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if stride is negative.");
	ctx.glVertexAttribIPointer(0, 1, GL_BYTE, -1, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_OPERATION is generated a non-zero vertex array object is bound, zero is bound to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.");
	GLuint vao = 0;
	GLbyte offset = 1;
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.expectError(GL_NO_ERROR);

	ctx.glVertexAttribIPointer(0, 1, GL_BYTE, 0, &offset);
	ctx.expectError(GL_INVALID_OPERATION);

	ctx.glBindVertexArray(0);
	ctx.glDeleteVertexArrays(1, &vao);
	ctx.expectError(GL_NO_ERROR);
	ctx.endSection();
}

void vertex_attrib_format (NegativeTestContext& ctx)
{
	int		maxVertexAttribs				= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	int		maxVertexAttribRelativeOffset	= ctx.getInteger(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
	GLuint	vao								= 0;

	ctx.beginSection("GL_INVALID_VALUE is generated if attribindex is greater than or equal to the value of MAX_VERTEX_ATTRIBS.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribFormat(maxVertexAttribs, 4, GL_FLOAT, GL_FALSE, maxVertexAttribRelativeOffset);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if size is not one of 1, 2, 3, 4.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribFormat(1, 0, GL_FLOAT, GL_FALSE, maxVertexAttribRelativeOffset);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the parameter token names allowed.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribFormat(1, 4, 1, GL_FALSE, 0);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_OPERATION is generated if type is not a token name allowed.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(0);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 0);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_OPERATION is generated if type is GL_INT_2_10_10_10_REV and size is not 4.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribFormat(1, 3, GL_INT_2_10_10_10_REV, GL_FALSE, 0);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_OPERATION is generated if type is GL_UNSIGNED_INT_2_10_10_10_REV and size is not 4.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribFormat(1, 3, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 0);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if relativeoffset is larger than the value of GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, maxVertexAttribRelativeOffset + 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void vertex_attrib_i_format (NegativeTestContext& ctx)
{
	int		maxVertexAttribs				= ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
	int		maxVertexAttribRelativeOffset	= ctx.getInteger(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
	GLuint	vao								= 0;

	ctx.beginSection("GL_INVALID_VALUE is generated if attribindex is greater than or equal to the value of GL_MAX_VERTEX_ATTRIBS.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribIFormat(maxVertexAttribs, 4, GL_INT, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if size is not one the values 1, 2, 3, 4.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribIFormat(1, 0, GL_INT, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the parameter token names allowed.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribIFormat(1, 4, GL_FLOAT, 0);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_OPERATION is generated if type is not a token name allowed.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(0);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribIFormat(1, 4, GL_INT, 0);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if relativeoffset is larger than the value of GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
	ctx.glGenVertexArrays(1, &vao);
	ctx.glBindVertexArray(vao);
	ctx.glBindBuffer(GL_ARRAY_BUFFER, 0);
	ctx.glVertexAttribIFormat(1, 4, GL_INT, maxVertexAttribRelativeOffset + 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void enable_vertex_attrib_array (NegativeTestContext& ctx)
{
	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);

	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	ctx.glEnableVertexAttribArray(maxVertexAttribs);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void disable_vertex_attrib_array (NegativeTestContext& ctx)
{
	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);

	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	ctx.glDisableVertexAttribArray(maxVertexAttribs);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void gen_vertex_arrays (NegativeTestContext& ctx)
{
	GLuint arrays = 0;

	ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
	ctx.glGenVertexArrays(-1, &arrays);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void bind_vertex_array (NegativeTestContext& ctx)
{
	ctx.beginSection("GL_INVALID_OPERATION is generated if array is not zero or the name of an existing vertex array object.");
	ctx.glBindVertexArray(-1);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();
}

void delete_vertex_arrays (NegativeTestContext& ctx)
{
	ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
	ctx.glDeleteVertexArrays(-1, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void vertex_attrib_divisor (NegativeTestContext& ctx)
{
	int maxVertexAttribs = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);

	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
	ctx.glVertexAttribDivisor(maxVertexAttribs, 0);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();
}

void draw_arrays (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawArrays(-1, 0, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawArrays(GL_POINTS, 0, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawArrays(GL_POINTS, 0, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_arrays_invalid_program (NegativeTestContext& ctx)
{
	GLuint fbo = 0;
	ctx.glUseProgram(0);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawArrays(-1, 0, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawArrays(GL_POINTS, 0, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawArrays(GL_POINTS, 0, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();
}

void draw_arrays_incomplete_primitive (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawArrays(-1, 0, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawArrays(GL_TRIANGLES, 0, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawArrays(GL_TRIANGLES, 0, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_elements (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	GLuint						buf		= 0;
	GLuint						tfID	= 0;
	GLbyte						indices[1]	= {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElements(GL_POINTS, 1, -1, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
	{
		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
		const char* tfVarying = "gl_Position";

		ctx.glGenBuffers(1, &buf);
		ctx.glGenTransformFeedbacks(1, &tfID);

		ctx.glUseProgram(program.getProgram());
		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
		ctx.glLinkProgram(program.getProgram());
		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
		ctx.glBeginTransformFeedback(GL_POINTS);
		ctx.expectError(GL_NO_ERROR);

		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_INVALID_OPERATION);

		ctx.glPauseTransformFeedback();
		ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_NO_ERROR);

		ctx.glEndTransformFeedback();
		ctx.glDeleteBuffers(1, &buf);
		ctx.glDeleteTransformFeedbacks(1, &tfID);
		ctx.expectError(GL_NO_ERROR);
		ctx.endSection();
	}

	ctx.glUseProgram(0);
}

void draw_elements_invalid_program (NegativeTestContext& ctx)
{
	ctx.glUseProgram(0);
	GLuint	fbo			= 0;
	GLbyte indices[1]	= {0};

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElements(GL_POINTS, 1, -1, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElements(GL_POINTS, 1, GL_FLOAT, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawElements(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();
}

void draw_elements_incomplete_primitive (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	GLuint						buf		= 0;
	GLuint						tfID	= 0;
	GLbyte						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElements(-1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElements(GL_TRIANGLES, 1, -1, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElements(GL_TRIANGLES, 1, GL_FLOAT, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawElements(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
	{
		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
		const char* tfVarying= "gl_Position";

		ctx.glGenBuffers(1, &buf);
		ctx.glGenTransformFeedbacks(1, &tfID);

		ctx.glUseProgram(program.getProgram());
		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
		ctx.glLinkProgram(program.getProgram());
		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
		ctx.glBeginTransformFeedback(GL_TRIANGLES);
		ctx.expectError(GL_NO_ERROR);

		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_INVALID_OPERATION);

		ctx.glPauseTransformFeedback();
		ctx.glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_NO_ERROR);

		ctx.glEndTransformFeedback();
		ctx.glDeleteBuffers(1, &buf);
		ctx.glDeleteTransformFeedbacks(1, &tfID);
		ctx.expectError(GL_NO_ERROR);
		ctx.endSection();
	}

	ctx.glUseProgram(0);
}

void draw_elements_base_vertex (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");

	GLuint				fbo = 0;
	GLuint				indices[1] = {0};

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElementsBaseVertex(-1, 1, GL_UNSIGNED_INT, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, -1, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_FLOAT, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawElementsBaseVertex(GL_POINTS, -1, GL_UNSIGNED_INT, indices, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_UNSIGNED_INT, indices, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();
}

void draw_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");

	GLuint						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);

	glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));

	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
	ctx.glUseProgram(program.getProgram());
	ctx.glDrawElementsBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, indices, 1);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_arrays_instanced (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);
	ctx.glVertexAttribDivisor(0, 1);
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawArraysInstanced(-1, 0, 1, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
	ctx.glDrawArraysInstanced(GL_POINTS, 0, -1, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_arrays_instanced_invalid_program (NegativeTestContext& ctx)
{
	ctx.glUseProgram(0);
	GLuint fbo = 0;
	ctx.glVertexAttribDivisor(0, 1);
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawArraysInstanced(-1, 0, 1, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
	ctx.glDrawArraysInstanced(GL_POINTS, 0, -1, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawArraysInstanced(GL_POINTS, 0, 1, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();
}

void draw_arrays_instanced_incomplete_primitive (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glVertexAttribDivisor(0, 1);
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawArraysInstanced(-1, 0, 1, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
	ctx.glDrawArraysInstanced(GL_TRIANGLES, 0, -1, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glDrawArraysInstanced(GL_TRIANGLES, 0, 1, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawArraysInstanced(GL_TRIANGLES, 0, 1, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_elements_instanced (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	GLuint						buf		= 0;
	GLuint						tfID	= 0;
	GLbyte						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.glVertexAttribDivisor(0, 1);
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, indices, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
	{
		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
		const char* tfVarying = "gl_Position";

		ctx.glGenBuffers(1, &buf);
		ctx.glGenTransformFeedbacks(1, &tfID);

		ctx.glUseProgram(program.getProgram());
		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
		ctx.glLinkProgram(program.getProgram());
		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
		ctx.glBeginTransformFeedback(GL_POINTS);
		ctx.expectError(GL_NO_ERROR);

		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
		ctx.expectError(GL_INVALID_OPERATION);

		ctx.glPauseTransformFeedback();
		ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
		ctx.expectError(GL_NO_ERROR);

		ctx.glEndTransformFeedback();
		ctx.glDeleteBuffers(1, &buf);
		ctx.glDeleteTransformFeedbacks(1, &tfID);
		ctx.expectError(GL_NO_ERROR);
		ctx.endSection();
	}

	ctx.glUseProgram(0);
}

void draw_elements_instanced_invalid_program (NegativeTestContext& ctx)
{
	ctx.glUseProgram(0);
	GLuint fbo = 0;
	GLbyte indices[1] = {0};
	ctx.glVertexAttribDivisor(0, 1);
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElementsInstanced(GL_POINTS, 1, -1, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_FLOAT, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
	ctx.glDrawElementsInstanced(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glDrawElementsInstanced(GL_POINTS, 11, GL_UNSIGNED_BYTE, indices, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElementsInstanced(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();
}

void draw_elements_instanced_incomplete_primitive (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	GLuint						buf		= 0;
	GLuint						tfID	= 0;
	GLbyte						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.glVertexAttribDivisor(0, 1);
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElementsInstanced(-1, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, -1, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_FLOAT, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
	ctx.glDrawElementsInstanced(GL_TRIANGLES, -1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glDrawElementsInstanced(GL_TRIANGLES, 11, GL_UNSIGNED_BYTE, indices, -1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
	{
		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
		const char* tfVarying= "gl_Position";

		ctx.glGenBuffers(1, &buf);
		ctx.glGenTransformFeedbacks(1, &tfID);

		ctx.glUseProgram(program.getProgram());
		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
		ctx.glLinkProgram(program.getProgram());
		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
		ctx.glBeginTransformFeedback(GL_TRIANGLES);
		ctx.expectError(GL_NO_ERROR);

		ctx.glDrawElementsInstanced(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices, 1);
		ctx.expectError(GL_INVALID_OPERATION);

		ctx.glPauseTransformFeedback();
		ctx.glDrawElementsInstanced	(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, indices, 1);
		ctx.expectError(GL_NO_ERROR);

		ctx.glEndTransformFeedback();
		ctx.glDeleteBuffers(1, &buf);
		ctx.glDeleteTransformFeedbacks(1, &tfID);
		ctx.expectError(GL_NO_ERROR);
		ctx.endSection();
	}

	ctx.glUseProgram(0);
}

void draw_elements_instanced_base_vertex (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");

	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	GLbyte						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program			(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.glVertexAttribDivisor(0, 1);
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawElementsInstancedBaseVertex(-1, 1, GL_UNSIGNED_BYTE, indices, 1, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, -1, indices, 1, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_FLOAT, indices, 1, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count or primcount are negative.");
	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, -1, GL_UNSIGNED_BYTE, indices, 1, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 11, GL_UNSIGNED_BYTE, indices, -1, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawElementsInstancedBaseVertex(GL_POINTS, 1, GL_UNSIGNED_BYTE, indices, 1, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_elements_instanced_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");

	GLuint						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));

	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
	ctx.glUseProgram(geometryProgram.getProgram());
	ctx.glDrawElementsInstancedBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, indices, 1, 1);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_range_elements (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	GLuint						buf		= 0;
	GLuint						tfID	= 0;
	GLbyte						indices[1]	= {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
	{
		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
		const char* tfVarying= "gl_Position";

		ctx.glGenBuffers(1, &buf);
		ctx.glGenTransformFeedbacks(1, &tfID);

		ctx.glUseProgram(program.getProgram());
		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
		ctx.glLinkProgram(program.getProgram());
		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
		ctx.glBeginTransformFeedback(GL_POINTS);
		ctx.expectError(GL_NO_ERROR);

		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_INVALID_OPERATION);

		ctx.glPauseTransformFeedback();
		ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_NO_ERROR);

		ctx.glEndTransformFeedback();
		ctx.glDeleteBuffers(1, &buf);
		ctx.glDeleteTransformFeedbacks(1, &tfID);
		ctx.expectError(GL_NO_ERROR);
		ctx.endSection();
	}

	ctx.glUseProgram(0);
}

void draw_range_elements_invalid_program (NegativeTestContext& ctx)
{
	ctx.glUseProgram(0);
	GLuint fbo = 0;
	GLbyte indices[1] = {0};

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, -1, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_FLOAT, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
	ctx.glDrawRangeElements(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawRangeElements(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();
}

void draw_range_elements_incomplete_primitive (NegativeTestContext& ctx)
{
	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	GLuint						fbo		= 0;
	GLuint						buf		= 0;
	GLuint						tfID	= 0;
	GLbyte						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawRangeElements(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, -1, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_FLOAT, indices);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, -1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
	ctx.glDrawRangeElements(GL_TRIANGLES, 1, 0, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) // GL_EXT_geometry_shader removes error
	{
		ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is active and not paused.");
		const char* tfVarying = "gl_Position";

		ctx.glGenBuffers(1, &buf);
		ctx.glGenTransformFeedbacks(1, &tfID);

		ctx.glUseProgram(program.getProgram());
		ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
		ctx.glLinkProgram(program.getProgram());
		ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
		ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
		ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
		ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
		ctx.glBeginTransformFeedback(GL_TRIANGLES);
		ctx.expectError(GL_NO_ERROR);

		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_INVALID_OPERATION);

		ctx.glPauseTransformFeedback();
		ctx.glDrawRangeElements(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_BYTE, indices);
		ctx.expectError(GL_NO_ERROR);

		ctx.glEndTransformFeedback();
		ctx.glDeleteBuffers(1, &buf);
		ctx.glDeleteTransformFeedbacks(1, &tfID);
		ctx.expectError(GL_NO_ERROR);
		ctx.endSection();
	}

	ctx.glUseProgram(0);
}

void draw_range_elements_base_vertex (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");

	GLuint						fbo		= 0;
	GLbyte						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"]			= getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));

	ctx.glUseProgram(program.getProgram());
	ctx.expectError(GL_NO_ERROR);

	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
	ctx.glDrawRangeElementsBaseVertex(-1, 0, 1, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_ENUM is generated if type is not one of the accepted values.");
	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, -1, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_FLOAT, indices, 1);
	ctx.expectError(GL_INVALID_ENUM);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, -1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_VALUE is generated if end < start.");
	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 1, 0, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_VALUE);
	ctx.endSection();

	ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
	ctx.glDrawRangeElementsBaseVertex(GL_POINTS, 0, 1, 1, GL_UNSIGNED_BYTE, indices, 1);
	ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.endSection();

	ctx.glUseProgram(0);
}

void draw_range_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");

	GLuint						indices[1] = {0};
	map<string, string>			args;
	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));

	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
	ctx.glUseProgram(geometryProgram.getProgram());
	ctx.glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_INT, indices, 1);
	ctx.expectError(GL_INVALID_OPERATION);
	ctx.endSection();

	ctx.glUseProgram(0);
}

std::vector<FunctionContainer> getNegativeVertexArrayApiTestFunctions ()
{
	FunctionContainer funcs[] =
	{
		{vertex_attribf,												"vertex_attribf",												"Invalid glVertexAttrib{1234}f() usage"				},
		{vertex_attribfv,												"vertex_attribfv",												"Invalid glVertexAttrib{1234}fv() usage"			},
		{vertex_attribi4,												"vertex_attribi4",												"Invalid glVertexAttribI4{i|ui}f() usage"			},
		{vertex_attribi4v,												"vertex_attribi4v",												"Invalid glVertexAttribI4{i|ui}fv() usage"			},
		{vertex_attrib_pointer,											"vertex_attrib_pointer",										"Invalid glVertexAttribPointer() usage"				},
		{vertex_attrib_i_pointer,										"vertex_attrib_i_pointer",										"Invalid glVertexAttribPointer() usage"				},
		{vertex_attrib_format,											"vertex_attrib_format",											"Invalid glVertexAttribFormat() usage"				},
		{vertex_attrib_i_format,										"vertex_attrib_i_format",										"Invalid glVertexAttribIFormat() usage"				},
		{enable_vertex_attrib_array,									"enable_vertex_attrib_array",									"Invalid glEnableVertexAttribArray() usage"			},
		{disable_vertex_attrib_array,									"disable_vertex_attrib_array",									"Invalid glDisableVertexAttribArray() usage"		},
		{gen_vertex_arrays,												"gen_vertex_arrays",											"Invalid glGenVertexArrays() usage"					},
		{bind_vertex_array,												"bind_vertex_array",											"Invalid glBindVertexArray() usage"					},
		{delete_vertex_arrays,											"delete_vertex_arrays",											"Invalid glDeleteVertexArrays() usage"				},
		{vertex_attrib_divisor,											"vertex_attrib_divisor",										"Invalid glVertexAttribDivisor() usage"				},
		{draw_arrays,													"draw_arrays",													"Invalid glDrawArrays() usage"						},
		{draw_arrays_invalid_program,									"draw_arrays_invalid_program",									"Invalid glDrawArrays() usage"						},
		{draw_arrays_incomplete_primitive,								"draw_arrays_incomplete_primitive",								"Invalid glDrawArrays() usage"						},
		{draw_elements,													"draw_elements",												"Invalid glDrawElements() usage"					},
		{draw_elements_base_vertex,										"draw_elements_base_vertex",									"Invalid glDrawElementsBaseVertex() usage"			},
		{draw_elements_base_vertex_primitive_mode_mismatch,				"draw_elements_base_vertex_primitive_mode_mismatch",			"Invalid glDrawElementsBaseVertex() usage"			},
		{draw_elements_invalid_program,									"draw_elements_invalid_program",								"Invalid glDrawElements() usage"					},
		{draw_elements_incomplete_primitive,							"draw_elements_incomplete_primitive",							"Invalid glDrawElements() usage"					},
		{draw_arrays_instanced,											"draw_arrays_instanced",										"Invalid glDrawArraysInstanced() usage"				},
		{draw_arrays_instanced_invalid_program,							"draw_arrays_instanced_invalid_program",						"Invalid glDrawArraysInstanced() usage"				},
		{draw_arrays_instanced_incomplete_primitive,					"draw_arrays_instanced_incomplete_primitive",					"Invalid glDrawArraysInstanced() usage"				},
		{draw_elements_instanced,										"draw_elements_instanced",										"Invalid glDrawElementsInstanced() usage"			},
		{draw_elements_instanced_invalid_program,						"draw_elements_instanced_invalid_program",						"Invalid glDrawElementsInstanced() usage"			},
		{draw_elements_instanced_incomplete_primitive,					"draw_elements_instanced_incomplete_primitive",					"Invalid glDrawElementsInstanced() usage"			},
		{draw_elements_instanced_base_vertex,							"draw_elements_instanced_base_vertex",							"Invalid glDrawElementsInstancedBaseVertex() usage"	},
		{draw_elements_instanced_base_vertex_primitive_mode_mismatch,	"draw_elements_instanced_base_vertex_primitive_mode_mismatch",	"Invalid glDrawElementsInstancedBaseVertex() usage"	},
		{draw_range_elements,											"draw_range_elements",											"Invalid glDrawRangeElements() usage"				},
		{draw_range_elements_invalid_program,							"draw_range_elements_invalid_program",							"Invalid glDrawRangeElements() usage"				},
		{draw_range_elements_incomplete_primitive,						"draw_range_elements_incomplete_primitive",						"Invalid glDrawRangeElements() usage"				},
		{draw_range_elements_base_vertex,								"draw_range_elements_base_vertex",								"Invalid glDrawRangeElementsBaseVertex() usage"		},
		{draw_range_elements_base_vertex_primitive_mode_mismatch,		"draw_range_elements_base_vertex_primitive_mode_mismatch",		"Invalid glDrawRangeElementsBaseVertex() usage"		},
	};

	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
}

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