/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL Module
 * ---------------------------------------
 *
 * Copyright 2017 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 Robustness tests for KHR_robustness.
 *//*--------------------------------------------------------------------*/

#include "teglRobustnessTests.hpp"

#include "tcuTestLog.hpp"
#include "tcuStringTemplate.hpp"

#include "egluConfigFilter.hpp"
#include "egluStrUtil.hpp"
#include "egluUtil.hpp"
#include "eglwLibrary.hpp"

#include "gluStrUtil.hpp"
#include "gluShaderProgram.hpp"
#include "gluDrawUtil.hpp"

#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "deSTLUtil.hpp"
#include "deStringUtil.hpp"
#include "deThread.hpp"
#include "deSharedPtr.hpp"

#include <set>

using std::string;
using std::vector;
using std::set;
using tcu::TestLog;

using namespace eglw;

DE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY	== 0x8256);
DE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET		== 0x8252);
DE_STATIC_ASSERT(GL_NO_RESET_NOTIFICATION		== 0x8261);

namespace deqp
{
namespace egl
{
namespace
{

enum ContextResetType
{
	CONTEXTRESETTYPE_INFINITE_LOOP,
	CONTEXTRESETTYPE_SHADER_OOB,
	CONTEXTRESETTYPE_FIXED_FUNC_OOB,
};

enum ShaderType
{
	SHADERTYPE_VERT,
	SHADERTYPE_FRAG,
	SHADERTYPE_COMPUTE,
	SHADERTYPE_VERT_AND_FRAG,
};

enum ReadWriteType
{
	READWRITETYPE_READ,
	READWRITETYPE_WRITE,
};

enum ResourceType
{
	RESOURCETYPE_UBO,
	RESOURCETYPE_SSBO,
	RESOURCETYPE_LOCAL_ARRAY,
};

enum FixedFunctionType
{
	FIXEDFUNCTIONTYPE_INDICES,
	FIXEDFUNCTIONTYPE_VERTICES,
};

enum RobustAccessType
{
	ROBUSTACCESS_TRUE,
	ROBUSTACCESS_FALSE,
};

void requireEGLExtension (const Library& egl, EGLDisplay eglDisplay, const char* requiredExtension)
{
	if (!eglu::hasExtension(egl, eglDisplay, requiredExtension))
		TCU_THROW(NotSupportedError, (string(requiredExtension) + " not supported").c_str());
}

bool isWindow (const eglu::CandidateConfig& c)
{
	return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
}

template <deUint32 Type>
bool renderable (const eglu::CandidateConfig& c)
{
	return (c.renderableType() & Type) == Type;
}

eglu::ConfigFilter getRenderableFilter (deUint32 bits)
{
	switch (bits)
	{
		case EGL_OPENGL_ES2_BIT:	return renderable<EGL_OPENGL_ES2_BIT>;
		case EGL_OPENGL_ES3_BIT:	return renderable<EGL_OPENGL_ES3_BIT>;
		case EGL_OPENGL_BIT:		return renderable<EGL_OPENGL_BIT>;
		default:
			DE_FATAL("Unknown EGL bitfied value");
			return renderable<0>;
	}
}

const char* eglResetNotificationStrategyToString (EGLint strategy)
{
	switch (strategy)
	{
		case EGL_NO_RESET_NOTIFICATION_KHR:		return "EGL_NO_RESET_NOTIFICATION_KHR";
		case EGL_LOSE_CONTEXT_ON_RESET_KHR:		return "EGL_LOSE_CONTEXT_ON_RESET_KHR";
		default:
			return "<Unknown>";
	}
}

void logAttribList (const EglTestContext& eglTestCtx, const EGLint* attribList)
{
	const EGLint*		iter = &(attribList[0]);
	std::ostringstream	attribListString;

	while ((*iter) != EGL_NONE)
	{
		switch (*iter)
		{
		//	case EGL_CONTEXT_CLIENT_VERSION:
			case EGL_CONTEXT_MAJOR_VERSION_KHR:
				iter++;
				attribListString << "EGL_CONTEXT_CLIENT_VERSION, " << (*iter) << ", ";
				iter++;
				break;

			case EGL_CONTEXT_MINOR_VERSION_KHR:
				iter++;
				attribListString << "EGL_CONTEXT_MINOR_VERSION_KHR, " << (*iter) << ", ";
				iter++;
				break;

			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
				iter++;
				attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, "
								 << eglResetNotificationStrategyToString(*iter) << ", ";
				iter++;
				break;

			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
				iter++;
				attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, "
								 << eglResetNotificationStrategyToString(*iter) << ", ";
				iter++;
				break;

			case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
				iter++;
				attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, ";

				if (*iter == EGL_FALSE || *iter == EGL_TRUE)
					attribListString << (*iter ? "EGL_TRUE" : "EGL_FALSE") << ", ";
				else
					attribListString << (*iter) << ", ";
				iter++;
				break;

			default:
				DE_FATAL("Unsupported attribute");
		}
	}

	attribListString << "EGL_NONE";
	eglTestCtx.getTestContext().getLog() << TestLog::Message
										 << "EGL attrib list: { " << attribListString.str() << " }\n\n"
										 << TestLog::EndMessage;
}

class RobustnessTestCase: public TestCase
{
public:
	class Params
	{
	public:
							Params					(void) {};

							Params					(const string&				name,
													 const string&				description,
													 const RobustAccessType&	robustAccessType,
													 const ContextResetType&	contextResetType,
													 const FixedFunctionType&	fixedFunctionType);

							Params					(const string&				name,
													 const string&				description,
													 const ContextResetType&	contextResetType,
													 const ShaderType&			shaderType);

							Params					(const string&				name,
													 const string&				description,
													 const RobustAccessType&	robustAccessType,
													 const ContextResetType&	contextResetType,
													 const ShaderType&			shaderType,
													 const ResourceType&		resourceType,
													 const ReadWriteType&		readWriteType);

		const string&				getName					(void) const { return m_name;				}
		const string&				getDescription			(void) const { return m_description;		}
		const ContextResetType&		getContextResetType		(void) const { return m_contextResetType;	}
		const ShaderType&			getShaderType			(void) const { return m_shaderType;			}
		const ResourceType&			getResourceType			(void) const { return m_resourceType;		}
		const ReadWriteType&		getReadWriteType		(void) const { return m_readWriteType;		}
		const FixedFunctionType&	getFixedFunctionType	(void) const { return m_fixedFunctionType;	}
		const RobustAccessType&		getRobustAccessType		(void) const { return m_robustAccessType;	}

	private:
		string				m_name;
		string				m_description;
		RobustAccessType	m_robustAccessType;
		ContextResetType	m_contextResetType;
		ShaderType			m_shaderType;
		ResourceType		m_resourceType;
		ReadWriteType		m_readWriteType;
		FixedFunctionType	m_fixedFunctionType;
	};

			RobustnessTestCase			(EglTestContext& eglTestCtx, const char* name, const char* description);
			RobustnessTestCase			(EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
			~RobustnessTestCase			(void);

	void	checkRequiredEGLExtensions	(const EGLint* attribList);

protected:
	Params					m_params;
	EGLDisplay				m_eglDisplay;
	EGLConfig				m_eglConfig;
	EGLSurface				m_eglSurface;

private:
	void					init					(void);
	void					deinit					(void);
	void					initEGLSurface			(void);
	EGLConfig				getEGLConfig			(void);

	eglu::NativeWindow*		m_window;
};

RobustnessTestCase::Params::Params (const string&				name,
									const string&				description,
									const RobustAccessType&		robustAccessType,
									const ContextResetType&		contextResetType,
									const FixedFunctionType&	fixedFunctionType)
	: m_name				(name)
	, m_description			(description)
	, m_robustAccessType	(robustAccessType)
	, m_contextResetType	(contextResetType)
	, m_fixedFunctionType	(fixedFunctionType)
{
}

RobustnessTestCase::Params::Params (const string&				name,
									const string&				description,
									const ContextResetType&		contextResetType,
									const ShaderType&			shaderType)
	: m_name				(name)
	, m_description			(description)
	, m_contextResetType	(contextResetType)
	, m_shaderType			(shaderType)
{
}

RobustnessTestCase::Params::Params (const string&				name,
									const string&				description,
									const RobustAccessType&		robustAccessType,
									const ContextResetType&		contextResetType,
									const ShaderType&			shaderType,
									const ResourceType&			resourceType,
									const ReadWriteType&		readWriteType)
	: m_name				(name)
	, m_description			(description)
	, m_robustAccessType	(robustAccessType)
	, m_contextResetType	(contextResetType)
	, m_shaderType			(shaderType)
	, m_resourceType		(resourceType)
	, m_readWriteType		(readWriteType)
{
}

RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description)
	: TestCase			(eglTestCtx, name, description)
	, m_eglDisplay		(EGL_NO_DISPLAY)
	, m_eglConfig		(0)
	, m_eglSurface		(EGL_NO_SURFACE)
	, m_window			(DE_NULL)
{
}

RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
	: TestCase			(eglTestCtx, name, description)
	, m_params			(params)
	, m_eglDisplay		(EGL_NO_DISPLAY)
	, m_eglConfig		(0)
	, m_eglSurface		(EGL_NO_SURFACE)
	, m_window			(DE_NULL)
{
}

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

void RobustnessTestCase::init (void)
{
	m_eglDisplay	= eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
	m_eglConfig		= getEGLConfig();

	initEGLSurface();
}

void RobustnessTestCase::deinit (void)
{
	const Library& egl = m_eglTestCtx.getLibrary();

	if (m_eglSurface != EGL_NO_SURFACE)
	{
		egl.destroySurface(m_eglDisplay, m_eglSurface);
		m_eglSurface = EGL_NO_SURFACE;
	}
	if (m_eglDisplay != EGL_NO_DISPLAY)
	{
		egl.terminate(m_eglDisplay);
		m_eglDisplay = EGL_NO_DISPLAY;
	}

	delete m_window;
	m_window = DE_NULL;
}

EGLConfig RobustnessTestCase::getEGLConfig (void)
{
	eglu::FilterList filters;
	filters << isWindow << getRenderableFilter(EGL_OPENGL_ES3_BIT);
	return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, filters);
}

void RobustnessTestCase::initEGLSurface (void)
{
	EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), bindAPI(EGL_OPENGL_ES_API));

	const eglu::NativeWindowFactory& factory =	eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());

	const eglu::WindowParams	windowParams	=	eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine()));
	m_window									=	factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL, windowParams);
	m_eglSurface								=	eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
}

glu::ApiType paramsToApiType (const RobustnessTestCase::Params& params)
{
	EGLint				minorVersion	= 0;
	if (params.getShaderType()		 == SHADERTYPE_COMPUTE	||
		params.getResourceType()	 == RESOURCETYPE_SSBO	||
		params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
	{
		minorVersion = 1;
	}

	return glu::ApiType::es(3, minorVersion);
}

void RobustnessTestCase::checkRequiredEGLExtensions (const EGLint* attribList)
{
	set<string>		requiredExtensions;
	vector<string>	extensions			= eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_eglDisplay);

	{
		const EGLint* iter = attribList;

		while ((*iter) != EGL_NONE)
		{
			switch (*iter)
			{
				case EGL_CONTEXT_MAJOR_VERSION_KHR: iter++;
					iter++;
					break;

				case EGL_CONTEXT_MINOR_VERSION_KHR:
					iter++;
					requiredExtensions.insert("EGL_KHR_create_context");
					iter++;
					break;

				case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
				case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
					iter++;
					requiredExtensions.insert("EGL_EXT_create_context_robustness");
					iter++;
					break;

				default:
					DE_ASSERT(DE_FALSE);
			}
		}
	}

	for (std::set<string>::const_iterator reqExt = requiredExtensions.begin(); reqExt != requiredExtensions.end(); ++reqExt)
	{
		if (!de::contains(extensions.begin(), extensions.end(), *reqExt))
		{
			const char* const extension = reqExt->c_str();
			requireEGLExtension(m_eglTestCtx.getLibrary(), m_eglDisplay, extension);
		}
	}
}

void checkRequiredGLSupport (const glw::Functions& gl, glu::ApiType requiredApi)
{
	if (!glu::hasExtension(gl, requiredApi, "GL_KHR_robustness") && !glu::hasExtension(gl, requiredApi, "GL_EXT_robustness"))
	{
		TCU_THROW(NotSupportedError, (string("GL_KHR_robustness and GL_EXT_robustness") + " not supported").c_str());
	}
	else
	{
		int realMinorVersion = 0;
		gl.getIntegerv(GL_MINOR_VERSION, &realMinorVersion);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Get minor version failed");

		if (realMinorVersion < requiredApi.getMinorVersion())
			TCU_THROW(NotSupportedError, "Test case requires GLES 3.1");
	}
}

void checkGLSupportForParams (const glw::Functions& gl, const RobustnessTestCase::Params& params)
{
	int minorVersion = 0;
	if (params.getShaderType()		  == SHADERTYPE_COMPUTE	||
		params.getResourceType()	  == RESOURCETYPE_SSBO	||
		params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
	{
		minorVersion = 1;
	}
	checkRequiredGLSupport(gl, glu::ApiType::es(3, minorVersion));
}

class RenderingContext
{
public:
							RenderingContext					(const EglTestContext&	eglTestCtx,
																 const EGLint*			attribList,
																 const EGLConfig&		config,
																 const EGLDisplay&		display,
																 const EGLContext&		sharedContext);
							~RenderingContext					(void);

	void					initGLFunctions						(glw::Functions* gl, const glu::ApiType apiType);
	void					makeCurrent							(const EGLSurface& surface);
	EGLContext				getContext							(void);

private:
	const EglTestContext&	m_eglTestCtx;
	const EGLint*			m_attribList;
	const EGLConfig&		m_config;
	const EGLDisplay&		m_display;
	const Library&			m_egl;

	EGLContext				m_context;

	void					createContext						(const EGLConfig& sharedConfig);
	void					destroyContext						(void);

							RenderingContext					(const RenderingContext&);
	RenderingContext&		operator=							(const RenderingContext&);
};

RenderingContext::RenderingContext (const EglTestContext&	 eglTestCtx,
									const EGLint*			 attribList,
									const EGLConfig&		 config,
									const EGLDisplay&		 display,
									const EGLContext&		 sharedContext)
	: m_eglTestCtx		(eglTestCtx)
	, m_attribList		(attribList)
	, m_config			(config)
	, m_display			(display)
	, m_egl				(eglTestCtx.getLibrary())
	, m_context			(EGL_NO_CONTEXT)
{
	logAttribList(eglTestCtx, m_attribList);
	createContext(sharedContext);
}

RenderingContext::~RenderingContext (void)
{
	destroyContext();
}

void RenderingContext::createContext (const EGLConfig& sharedContext)
{
	m_context = m_egl.createContext(m_display, m_config, sharedContext, m_attribList);
	EGLU_CHECK_MSG(m_egl, "eglCreateContext()");
}

void RenderingContext::destroyContext (void)
{
	EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

	if (m_context != EGL_NO_CONTEXT)
		m_egl.destroyContext(m_display, m_context);
}

void RenderingContext::makeCurrent (const EGLSurface& surface)
{
	EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, surface, surface, m_context));
}

void RenderingContext::initGLFunctions (glw::Functions *gl, const glu::ApiType apiType)
{
	// \todo [2017-03-23 pyry] Current version has 2 somewhat ugly hacks:
	//
	// 1) Core functions are loaded twice. We need glGetString(i) to query supported
	//    extensions to determine if we need to load EXT or KHR-suffixed robustness
	//    functions. This could be fixed by exposing glw::FunctionLoader in EglTestContext
	//    for example.
	//
	// 2) We assume that calling code will check for KHR_robustness or EXT_robustness
	//    support after calling initGLFunctions(). We could move the check here.

	m_eglTestCtx.initGLFunctions(gl, apiType);

	{
		const char* const	robustnessExt	= glu::hasExtension(*gl, apiType, "GL_KHR_robustness") ? "GL_KHR_robustness" : "GL_EXT_robustness";
		const char* const	extensions[]	= { robustnessExt };

		m_eglTestCtx.initGLFunctions(gl, apiType, DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
	}
}

EGLContext RenderingContext::getContext (void)
{
	return m_context;
}

class ContextReset
{
public:
						ContextReset				(glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
						ContextReset				(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType);
						ContextReset				(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);

	virtual				~ContextReset				(void) {};

	virtual void		setup						(void) = 0;
	virtual void		draw						(void) = 0;
	virtual void		teardown					(void) = 0;

	void				finish						(void);
	void				createSyncObject			(void);
	glw::GLint			getSyncStatus				(void);

	void				beginQuery					(void);
	void				endQuery					(void);
	glw::GLint			getError					(void);
	glw::GLint			getGraphicsResetStatus		(void);
	glw::GLuint			getQueryAvailability		(void);

	glw::GLsync			getSyncObject				(void) const { return m_sync; }
	glw::GLuint			getQueryID					(void) const { return m_queryID; }

	glw::Functions&		m_gl;
	tcu::TestLog&		m_log;
	ShaderType			m_shaderType;
	ResourceType		m_resourceType;
	ReadWriteType		m_readWriteType;
	FixedFunctionType	m_fixedFunctionType;

private:
						ContextReset				(const ContextReset&);
	ContextReset&		operator=					(const ContextReset&);

	glw::GLuint			m_queryID;
	glw::GLsync			m_sync;
};

ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
	: m_gl					(gl)
	, m_log					(log)
	, m_fixedFunctionType	(fixedFunctionType)
{
}

ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
	: m_gl				(gl)
	, m_log				(log)
	, m_shaderType		(shaderType)
	, m_resourceType	(resourceType)
	, m_readWriteType	(readWriteType)
{
}

ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType)
	: m_gl			(gl)
	, m_log			(log)
	, m_shaderType	(shaderType)
{
}

void ContextReset::finish (void)
{
	GLU_CHECK_GLW_CALL(m_gl, finish());
}

void ContextReset::createSyncObject (void)
{
	m_sync = m_gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFenceSync()");
}

glw::GLint ContextReset::getError (void)
{
	glw::GLint error;
	error = m_gl.getError();

	return error;
}

glw::GLint ContextReset::getGraphicsResetStatus (void)
{
	glw::GLint resetStatus;
	resetStatus = m_gl.getGraphicsResetStatus();

	return resetStatus;
}

glw::GLint ContextReset::getSyncStatus (void)
{
	glw::GLint syncStatus;
	m_gl.getSynciv(m_sync, GL_SYNC_STATUS, sizeof(glw::GLint), NULL, &syncStatus);

	return syncStatus;
}

void ContextReset::beginQuery (void)
{
	GLU_CHECK_GLW_CALL(m_gl, genQueries(1, &m_queryID));
	GLU_CHECK_GLW_CALL(m_gl, beginQuery(GL_ANY_SAMPLES_PASSED, m_queryID));
}

void ContextReset::endQuery (void)
{
	GLU_CHECK_GLW_CALL(m_gl, endQuery(GL_ANY_SAMPLES_PASSED));
}

glw::GLuint ContextReset::getQueryAvailability (void)
{
	glw::GLuint queryReady = GL_FALSE;
	m_gl.getQueryObjectuiv(m_queryID, GL_QUERY_RESULT_AVAILABLE, &queryReady);

	return queryReady;
}

class InfiniteLoop : public ContextReset
{
public:
						InfiniteLoop			(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType);
						~InfiniteLoop			(void);

	virtual void		setup					(void);
	virtual void		draw					(void);
	virtual void		teardown				(void);

private:
	glu::ProgramSources genComputeSource		(void);
	glu::ProgramSources genNonComputeSource		(void);
	glu::ProgramSources	genSources				(void);

	glw::GLuint			m_outputBuffer;
	glw::GLuint			m_coordinatesBuffer;
	glw::GLint			m_coordLocation;
};

InfiniteLoop::InfiniteLoop (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType)
	: ContextReset(gl, log, shaderType)
	, m_outputBuffer		(0)
	, m_coordinatesBuffer	(0)
	, m_coordLocation		(0)
{
}

InfiniteLoop::~InfiniteLoop (void)
{
	try
	{
		// Reset GL_CONTEXT_LOST error before destroying resources
		m_gl.getGraphicsResetStatus();
		teardown();
	}
	catch (...)
	{
		// Ignore GL errors from teardown()
	}
}

glu::ProgramSources InfiniteLoop::genSources(void)
{
	if (m_shaderType == SHADERTYPE_COMPUTE)
		return genComputeSource();
	else
		return genNonComputeSource();
}

glu::ProgramSources InfiniteLoop::genComputeSource(void)
{
	const char* const computeSource =
		"#version 310 es\n"
		"layout(local_size_x = 1, local_size_y = 1) in;\n"
		"uniform highp int u_iterCount;\n"
		"writeonly buffer Output { highp int b_output_int; };\n"
		"void main ()\n"
		"{\n"
		"	for (highp int i = 0; i < u_iterCount || u_iterCount < 0; ++i)\n"
		"		b_output_int = u_iterCount;\n"
		"}\n";

	return glu::ProgramSources() << glu::ComputeSource(computeSource);
}

glu::ProgramSources InfiniteLoop::genNonComputeSource (void)
{
	const bool isVertCase			= m_shaderType == SHADERTYPE_VERT;
	const bool isFragCase			= m_shaderType == SHADERTYPE_FRAG;
	const bool isVertAndFragment	= m_shaderType == SHADERTYPE_VERT_AND_FRAG;

	std::ostringstream vert, frag;

	vert << "#version 300 es\n"
		 << "in highp vec2 a_position;\n";

	frag << "#version 300 es\n";

	vert << "uniform highp int u_iterCount;\n";
	if (isFragCase || isVertAndFragment)
	{
		vert << "flat out highp int v_iterCount;\n";
		frag << "flat in highp int v_iterCount;\n";
	}

	if (isVertCase || isVertAndFragment)
	{
		vert << "out mediump vec4 v_color;\n";
		frag << "in mediump vec4 v_color;\n";
	}

	frag << "out mediump vec4 o_color;\n";

	vert << "\nvoid main (void)\n{\n"
		 << "	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		 << "	gl_PointSize = 1.0;\n";

	if (isFragCase || isVertAndFragment)
		vert << "	v_iterCount = u_iterCount;\n";

	frag << "\nvoid main (void)\n{\n";

	const std::string	iterCount	= (isVertCase ? "u_iterCount" : "v_iterCount");
	const std::string	loopHeader	= "	for (highp int i = 0; i < " + iterCount + " || " + iterCount + " < 0; ++i)\n";
	const char* const	body		= "color = cos(sin(color*1.25)*0.8);";

	if (isVertAndFragment)
	{
		vert << "	mediump vec4 color = " << "a_position.xyxy" << ";\n";
		vert << loopHeader << "		" << body << "\n";

		frag << "	mediump vec4 color = " << "gl_FragCoord" << ";\n";
		frag << loopHeader << "		" << body << "\n";
	}
	else
	{
		std::ostringstream&	op			= isVertCase ? vert : frag;
		op << "	mediump vec4 color = " << (isVertCase ? "a_position.xyxy" : "gl_FragCoord") << ";\n";
		op << loopHeader << "		" << body << "\n";
	}

	if (isVertCase || isVertAndFragment)
	{
		vert << "	v_color = color;\n";
		frag << "	o_color = v_color;\n";
	}
	else
		frag << "	o_color = color;\n";

	vert << "}\n";
	frag << "}\n";

	return glu::ProgramSources() << glu::VertexSource(vert.str()) << glu::FragmentSource(frag.str());
}

void InfiniteLoop::setup (void)
{
	glu::ShaderProgram program (m_gl, genSources());
	m_log << program;

	if (!program.isOk())
		TCU_FAIL("Failed to compile shader program");

	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));

	if (m_shaderType == SHADERTYPE_COMPUTE)
	{
		// Output buffer setup
		m_outputBuffer = 0;
		GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_outputBuffer));
		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, m_outputBuffer));
		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), DE_NULL, GL_DYNAMIC_DRAW));
		GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_outputBuffer));
	}
	else
	{
		const glw::GLfloat coords[] =
		{
			-1.0f, -1.0f,
			+1.0f, -1.0f,
			+1.0f, +1.0f,
			-1.0f, +1.0f
		};

		m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
		GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
		TCU_CHECK(m_coordLocation != (glw::GLint)-1);

		// Load the vertex data
		m_coordinatesBuffer = 0;
		GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
		GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
		GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
	}

	glw::GLint iterCountLocation = m_gl.getUniformLocation(program.getProgram(), "u_iterCount");
	GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
	TCU_CHECK(iterCountLocation != (glw::GLint)-1);

	// Set the iteration count (infinite)
	glw::GLint iterCount = -1;
	GLU_CHECK_GLW_CALL(m_gl, uniform1i(iterCountLocation, iterCount));
}

void InfiniteLoop::draw (void)
{
	if (m_shaderType == SHADERTYPE_COMPUTE)
		m_gl.dispatchCompute(1, 1, 1);
	else
	{
		const glw::GLushort indices[] = { 0, 1, 2, 2, 3, 0 };
		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
	}
}

void InfiniteLoop::teardown (void)
{
	if (m_shaderType != SHADERTYPE_COMPUTE)
	{
		if (m_coordLocation)
		{
			GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
			m_coordLocation = 0;
		}
	}

	if (m_outputBuffer)
	{
		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_outputBuffer));
		m_outputBuffer = 0;
	}

	if (m_coordinatesBuffer)
	{
		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
		m_coordinatesBuffer = 0;
	}

	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
}

class FixedFunctionOOB : public ContextReset
{
public:
							FixedFunctionOOB			(glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
							~FixedFunctionOOB			(void);

	struct TestConfig
	{
		int textureWidth;
		int textureHeight;
	};

	virtual void			setup						(void);
	virtual void			draw						(void);
	virtual void			teardown					(void);

private:
	glu::ProgramSources		genSources					(void);
	glw::GLuint				m_coordinatesBuffer;
	glw::GLint				m_coordLocation;
};

FixedFunctionOOB::FixedFunctionOOB (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
	: ContextReset(gl, log, fixedFunctionType)
	, m_coordinatesBuffer	(0)
	, m_coordLocation		(0)
{
}

FixedFunctionOOB::~FixedFunctionOOB (void)
{
	try
	{
		// Reset GL_CONTEXT_LOST error before destroying resources
		m_gl.getGraphicsResetStatus();
		teardown();
	}
	catch (...)
	{
		// Ignore GL errors from teardown()
	}
}

glu::ProgramSources FixedFunctionOOB::genSources (void)
{
	const char* const vert =
		"#version 300 es\n"
		"in highp vec4 a_position;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"}\n";

	const char* const frag =
		"#version 300 es\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor = vec4(1.0f);\n"
		"}\n";

	return glu::ProgramSources() << glu::VertexSource(vert) << glu::FragmentSource(frag);
}

void FixedFunctionOOB::setup (void)
{
	glu::ShaderProgram program(m_gl, genSources());

	m_log << program;

	if (!program.isOk())
		TCU_FAIL("Failed to compile shader program");

	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));

	const glw::GLfloat coords[] =
	{
		-1.0f, -1.0f,
		 1.0f, -1.0f,
		 1.0f,	1.0f,
		-1.0f,	1.0f
	};

	m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
	TCU_CHECK(m_coordLocation != (glw::GLint)-1);

	// Load the vertex data
	m_coordinatesBuffer = 0;
	GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
	GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
	GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
}

void FixedFunctionOOB::draw (void)
{
	const glw::GLint bad_indices[] = {0, 10, 100, 1000, 10000, 100000};

	if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_INDICES)
		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, bad_indices);
	else if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_VERTICES)
		m_gl.drawArrays(GL_TRIANGLES, 0, 1000);
	else
		DE_FATAL("Unknown fixed function type");
}

void FixedFunctionOOB::teardown (void)
{
	if (m_coordLocation)
	{
		GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
		m_coordLocation = 0;
	}

	if (m_coordinatesBuffer)
	{
		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
		m_coordinatesBuffer = 0;
	}

	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
}

class ShadersOOB : public ContextReset
{
public:
								ShadersOOB					(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);
								~ShadersOOB					(void);

	virtual void				setup						(void);
	virtual void				draw						(void);
	virtual void				teardown					(void);

private:
	static const int			s_numBindings				= 3;

	glw::GLuint					m_coordinatesBuffer;
	glw::GLint					m_coordLocation;

	bool						m_isUBO;
	bool						m_isRead;
	bool						m_isLocalArray;
	std::vector<glw::GLuint>	m_buffers;

	std::string					genVertexShader				(const std::string& shaderDecl, const std::string& shaderBody);
	std::string					genFragmentShader			(const std::string& shaderDecl, const std::string& shaderBody);
	std::string					genComputeShader			(const std::string& shaderDecl, const std::string& shaderBody);

	glu::ProgramSources			genNonComputeSource			(void);
	glu::ProgramSources			genComputeSource			(void);
	glu::ProgramSources			genSources					(void);
};

ShadersOOB::ShadersOOB (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
	: ContextReset(gl, log, shaderType, resourceType, readWriteType)
	, m_coordinatesBuffer	(0)
	, m_coordLocation		(0)
	, m_buffers				(s_numBindings, 0)
{
	m_isUBO			= (m_resourceType == RESOURCETYPE_UBO);
	m_isLocalArray	= (m_resourceType == RESOURCETYPE_LOCAL_ARRAY);
	m_isRead		= (m_readWriteType == READWRITETYPE_READ);
}

ShadersOOB::~ShadersOOB (void)
{
	try
	{
		// Reset GL_CONTEXT_LOST error before destroying resources
		m_gl.getGraphicsResetStatus();
		teardown();
	}
	catch (...)
	{
		// Ignore GL errors from teardown()
	}
}

std::string ShadersOOB::genVertexShader (const std::string& shaderDecl, const std::string& shaderBody)
{
	static const char* const s_simpleVertexShaderSource	=
		"#version 310 es\n"
		"in highp vec4 a_position;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"}\n";

	switch (m_shaderType)
	{
		case SHADERTYPE_VERT:
		case SHADERTYPE_VERT_AND_FRAG:
		{
			std::ostringstream vertexShaderSource;
			vertexShaderSource	<<	"#version 310 es\n"
								<<	"in highp vec4 a_position;\n"
								<<	"out highp vec4 v_color;\n"
								<<	shaderDecl << "\n"
								<<	"void main (void)\n"
								<<	"{\n"
								<<	"	highp vec4 color = vec4(0.0f);\n"
								<<	shaderBody << "\n"
								<<	"	v_color = color;\n"
								<<	"	gl_Position = a_position;\n"
								<<	"}\n";

			return vertexShaderSource.str();
		}

		case SHADERTYPE_FRAG:
			return s_simpleVertexShaderSource;

		default:
			DE_FATAL("Unknown shader type");
			return "";
	}
}

std::string ShadersOOB::genFragmentShader (const std::string& shaderDecl, const std::string& shaderBody)
{
	static const char* const s_simpleFragmentShaderSource =
		"#version 310 es\n"
		"in highp vec4 v_color;\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor = v_color;\n"
		"}\n";

	switch (m_shaderType)
	{
		case SHADERTYPE_VERT:
			return s_simpleFragmentShaderSource;

		case SHADERTYPE_FRAG:
		{
			std::ostringstream fragmentShaderSource;
			fragmentShaderSource	<<	"#version 310 es\n"
									<<	"layout(location = 0) out highp vec4 fragColor;\n"
									<<	shaderDecl << "\n"
									<<	"void main (void)\n"
									<<	"{\n"
									<<	"	highp vec4 color = vec4(0.0f);\n"
									<<	shaderBody << "\n"
									<<	"	fragColor = color;\n"
									<<	"}\n";

			return fragmentShaderSource.str();
		}
		case SHADERTYPE_VERT_AND_FRAG:
		{
			std::ostringstream fragmentShaderSource;
			fragmentShaderSource	<<	"#version 310 es\n"
									<<	"in highp vec4 v_color;\n"
									<<	"layout(location = 0) out highp vec4 fragColor;\n"
									<<	shaderDecl << "\n"
									<<	"void main (void)\n"
									<<	"{\n"
									<<	"	highp vec4 color = vec4(0.0f);\n"
									<<	shaderBody << "\n"
									<<	"	fragColor = color;\n"
									<<	"}\n";

			return fragmentShaderSource.str();
		}

		default:
			DE_FATAL("Unknown shader type");
			return "";
	}
}

std::string ShadersOOB::genComputeShader (const std::string& shaderDecl, const std::string& shaderBody)
{
	std::ostringstream computeShaderSource;

	computeShaderSource		<<	"#version 310 es\n"
							<<	"layout(local_size_x = 1, local_size_y = 1) in;\n"
							<<	"\n"
							<<	"layout(binding = 0) buffer Output {\n"
							<<	"	highp vec4 values;\n"
							<<	"} sb_out;\n"
							<<	"\n"
							<<	shaderDecl
							<<	"void main ()\n"
							<<	"{\n"
							<<	shaderBody
							<<	"}\n";

	return computeShaderSource.str();
}

glu::ProgramSources ShadersOOB::genNonComputeSource (void)
{
	std::ostringstream		shaderDecl;
	std::ostringstream		shaderBody;

	shaderDecl << "uniform highp int u_index;\n";

	if (m_isLocalArray)
	{
		const char* const readWriteStatement = (m_isRead)
											 ? "	color.x = color_out[u_index];\n"
											 : "	color[u_index] = color_out[0];\n";

		shaderBody	<< "	highp float color_out[4] = float[4](0.25f, 0.5f, 0.75f, 1.0f);\n"
					<< readWriteStatement;
	}
	else
	{
		const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";

		shaderDecl << "layout(std140, binding = 0) " << ((m_isUBO) ? "uniform" : "buffer") << " Block\n"
			<< "{\n"
			<< "	highp float color_out[4];\n"
			<< "} " << resName << "[" << s_numBindings << "];\n";

		const std::string readWriteStatement = (m_isRead)
											 ? "	color.x = " + resName + "[0].color_out[u_index];\n"
											 : "	color[u_index] = " + resName + "[0].color_out[0];\n";

		shaderBody << readWriteStatement;
	}

	return glu::ProgramSources() << glu::VertexSource(genVertexShader(shaderDecl.str(), shaderBody.str()))
								 << glu::FragmentSource(genFragmentShader(shaderDecl.str(), shaderBody.str()));
}

glu::ProgramSources ShadersOOB::genComputeSource (void)
{
	std::ostringstream		shaderDecl;
	std::ostringstream		shaderBody;

	shaderDecl << "uniform highp int u_index;\n";

	shaderBody	<< "	uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
				<< "	uint groupNdx = size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x;\n";

	if (m_isLocalArray)
	{
		const char* const readWriteStatement = (m_isRead)
											 ? "	sb_out.values.x = values[u_index];\n"
											 : "	sb_out.values[u_index] = values.x;\n";

		shaderBody	<< "	highp vec4 values = vec4(1.0f, 0.0f, 3.0f, 2.0f) * float(groupNdx);\n"
					<< readWriteStatement;
	}
	else
	{
		const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";

		shaderDecl	<< "layout(std140, binding = 1) " << ((m_isUBO) ? "uniform" : "buffer") << " Input\n"
					<< "{\n"
					<< "	highp vec4 values;\n"
					<< "} " << resName << "[" << s_numBindings << "];\n";

		std::string readWriteStatement = (m_isRead)
									   ? "	sb_out.values.x = " + resName + "[0].values[u_index] * float(groupNdx);\n"
									   : "	sb_out.values[u_index] = " + resName + "[0].values.x * float(groupNdx);\n";

		shaderBody << readWriteStatement;
	}

	return glu::ProgramSources() << glu::ComputeSource(genComputeShader(shaderDecl.str(), shaderBody.str()));
}

glu::ProgramSources ShadersOOB::genSources (void)
{
	if (m_shaderType == SHADERTYPE_COMPUTE)
		return genComputeSource();
	else
		return genNonComputeSource();
}

void ShadersOOB::setup (void)
{
	if (!m_isUBO && !m_isLocalArray && (m_shaderType != SHADERTYPE_COMPUTE))
	{
		// Check implementation limits for shader SSBO
		int shaderStorageBlockSupported = -1;
		const bool isVertex = (m_shaderType == SHADERTYPE_VERT || m_shaderType == SHADERTYPE_VERT_AND_FRAG) ? true : false;
		string shaderTypeStr = isVertex ? "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS" : "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS";

		GLU_CHECK_GLW_CALL(m_gl, getIntegerv(isVertex ? GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS : GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &shaderStorageBlockSupported));

		if (shaderStorageBlockSupported < (int)m_buffers.size())
			TCU_THROW(NotSupportedError, ("Test requires " + shaderTypeStr + " >= " + de::toString((int)m_buffers.size()) + ", got " + de::toString(shaderStorageBlockSupported)).c_str());
	}

	glu::ShaderProgram program(m_gl, genSources());

	m_log << program;

	if (!program.isOk())
		TCU_FAIL("Failed to compile shader program");

	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));

	const glw::GLint indexLocation = m_gl.getUniformLocation(program.getProgram(), "u_index");
	GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
	TCU_CHECK(indexLocation != (glw::GLint)-1);

	const glw::GLint index = -1;
	GLU_CHECK_GLW_CALL(m_gl, uniform1i(indexLocation, index));

	if (m_shaderType != SHADERTYPE_COMPUTE)
	{
		const glw::GLfloat coords[] =
		{
			-1.0f, -1.0f,
			+1.0f, -1.0f,
			+1.0f, +1.0f,
			-1.0f, +1.0f
		};

		// Setup vertices position
		m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
		GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
		TCU_CHECK(m_coordLocation != (glw::GLint)-1);

		// Load the vertex data
		m_coordinatesBuffer = 0;
		GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
		GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
		GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
	}

	// Create unused data for filling buffer objects
	const std::vector<tcu::Vec4> refValues(s_numBindings, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));

	if (m_isLocalArray && m_shaderType == SHADERTYPE_COMPUTE)
	{
		// Setup output buffer
		GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)1u, &m_buffers[0]));

		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[0]));
		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(tcu::Vec4), &(refValues[0]), GL_STATIC_DRAW));
		GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffers[0]));
	}
	else if (!m_isLocalArray)
	{
		// Set up interface block of buffer bindings
		GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));

		for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
		{
			const glw::GLenum resType	= m_isUBO && (m_shaderType != SHADERTYPE_COMPUTE || bufNdx != 0)
										? GL_UNIFORM_BUFFER
										: GL_SHADER_STORAGE_BUFFER;

			GLU_CHECK_GLW_CALL(m_gl, bindBuffer(resType, m_buffers[bufNdx]));
			GLU_CHECK_GLW_CALL(m_gl, bufferData(resType, sizeof(tcu::Vec4), &(refValues[bufNdx]), GL_STATIC_DRAW));
			GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(resType, bufNdx, m_buffers[bufNdx]));
		}
	}
}

void ShadersOOB::draw (void)
{
	if (m_shaderType == SHADERTYPE_COMPUTE)
		m_gl.dispatchCompute(1, 1, 1);
	else
	{
		const glw::GLuint indices[] = {0, 1, 2, 2, 3, 0};
		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
	}
}

void ShadersOOB::teardown (void)
{
	if (m_shaderType != SHADERTYPE_COMPUTE)
	{
		if (m_coordLocation)
		{
			GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
			m_coordLocation = 0;
		}
	}

	if (m_coordinatesBuffer)
	{
		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
		m_coordinatesBuffer = 0;
	}

	if (!m_isLocalArray)
	{
		if (!m_buffers.empty())
		{
			GLU_CHECK_GLW_CALL(m_gl, deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
			m_buffers.clear();
		}
	}

	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
}

class QueryRobustAccessCase : public RobustnessTestCase
{
public:
	QueryRobustAccessCase (EglTestContext& eglTestCtx, const char* name, const char* description)
		: RobustnessTestCase (eglTestCtx, name, description) {}

	TestCase::IterateResult	iterate		(void)
	{
		TestLog&	log		= m_testCtx.getLog();

		log << tcu::TestLog::Message
			<< "Check that after successfully creating a robust context the robust access query returned by glBooleanv() equals GL_TRUE\n\n"
			<< tcu::TestLog::EndMessage;

		const EGLint attribList[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
			EGL_NONE
		};

		checkRequiredEGLExtensions(attribList);

		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
		context.makeCurrent(m_eglSurface);

		glw::Functions gl;
		{
			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
			context.initGLFunctions(&gl, apiType);
			checkRequiredGLSupport(gl, apiType);
		}

		deUint8 robustAccessGL;
		gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");

		if (robustAccessGL != GL_TRUE)
		{
			log << TestLog::Message
				<< "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '" << robustAccessGL << "' expected GL_TRUE."
				<< TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		return STOP;
	}
};

class NoResetNotificationCase : public RobustnessTestCase
{
public:
	NoResetNotificationCase (EglTestContext& eglTestCtx, const char* name, const char* description)
		: RobustnessTestCase (eglTestCtx, name, description) {}

	TestCase::IterateResult	iterate		(void)
	{
		TestLog&	log		= m_testCtx.getLog();

		log << tcu::TestLog::Message
			<< "Check the reset notification strategy returned by glGetIntegerv() equals GL_NO_RESET_NOTIFICATION\n\n"
			<< tcu::TestLog::EndMessage;

		const EGLint attribList[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
			EGL_NONE
		};

		checkRequiredEGLExtensions(attribList);

		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
		context.makeCurrent(m_eglSurface);

		glw::Functions gl;
		{
			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
			context.initGLFunctions(&gl, apiType);
			checkRequiredGLSupport(gl, apiType);
		}

		deUint8 robustAccessGL;
		gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");

		glw::GLint reset = 0;
		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");

		if (reset != GL_NO_RESET_NOTIFICATION)
		{
			log	<< tcu::TestLog::Message
				<< "Test failed! glGetIntegerv() returned wrong value. [" << glu::getErrorStr(reset) << ", expected " << glu::getErrorStr(GL_NO_RESET_NOTIFICATION) << "]"
				<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

		GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		return STOP;
	}
};

class LoseContextOnResetCase : public RobustnessTestCase
{
public:
	LoseContextOnResetCase (EglTestContext& eglTestCtx, const char* name, const char* description)
		: RobustnessTestCase(eglTestCtx, name, description) {}

	TestCase::IterateResult	iterate		(void)
	{
		TestLog&	log		= m_testCtx.getLog();

		log << tcu::TestLog::Message
			<< "Check the reset notification strategy returned by glGetIntegerv() equals GL_LOSE_CONTEXT_ON_RESET\n\n"
			<< tcu::TestLog::EndMessage;

		const EGLint attribList[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
			EGL_NONE
		};

		checkRequiredEGLExtensions(attribList);

		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
		context.makeCurrent(m_eglSurface);

		glw::Functions gl;
		{
			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
			context.initGLFunctions(&gl, apiType);
			checkRequiredGLSupport(gl, apiType);
		}
		glw::GLint reset = 0;
		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");

		if (reset != GL_LOSE_CONTEXT_ON_RESET)
		{
			log	<< tcu::TestLog::Message
				<< "Test failed! glGetIntegerv() returned wrong value. [" << reset << ", expected " << glu::getErrorStr(GL_LOSE_CONTEXT_ON_RESET) << "]"
				<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

		log << tcu::TestLog::Message
			<< "Check the graphics reset status returned by glGetGraphicsResetStatus() "
			<< "equals GL_NO_ERROR\n"
			<< tcu::TestLog::EndMessage;

		GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		return STOP;
	}
};

de::SharedPtr<ContextReset> contextResetFactory (const RobustnessTestCase::Params params, glw::Functions& gl, tcu::TestLog& log)
{
	if (params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP)
		return de::SharedPtr<ContextReset>(new InfiniteLoop(gl, log, params.getShaderType()));

	if (params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
		return de::SharedPtr<ContextReset>(new FixedFunctionOOB(gl, log, params.getFixedFunctionType()));

	if (params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
		return de::SharedPtr<ContextReset>(new ShadersOOB(gl, log, params.getShaderType(), params.getResourceType(), params.getReadWriteType()));
	else
	{
		DE_FATAL("Unknown context reset type");
		return de::SharedPtr<ContextReset>(DE_NULL);
	}
}

class ContextResetCase : public RobustnessTestCase
{

public:
							ContextResetCase		(EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
	virtual					~ContextResetCase		(void) {};

	virtual void			provokeReset			(de::SharedPtr<ContextReset>& contextReset) = 0;
	virtual void			waitForReset			(de::SharedPtr<ContextReset>& contextReset) = 0;
	virtual void			passAndLog				(de::SharedPtr<ContextReset>& contextReset) = 0;

	TestCase::IterateResult iterate					(void);
	void					execute					(glw::Functions& gl);

private:
						ContextResetCase			(const ContextResetCase&);
	ContextResetCase&	operator=					(const ContextResetCase&);
};

ContextResetCase::ContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
	: RobustnessTestCase (eglTestCtx, name, description, params) {}

TestCase::IterateResult ContextResetCase::iterate (void)
{
	glw::Functions	gl;

	const EGLint attribList[] =
	{
		EGL_CONTEXT_CLIENT_VERSION, 3,
		EGL_CONTEXT_MINOR_VERSION_KHR, 0,
		EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, (m_params.getRobustAccessType() == ROBUSTACCESS_TRUE) ? EGL_TRUE : EGL_FALSE,
		EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
		EGL_NONE
	};

	checkRequiredEGLExtensions(attribList);

	RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
	context.makeCurrent(m_eglSurface);

	{
		const glu::ApiType apiType = paramsToApiType(m_params);
		context.initGLFunctions(&gl, apiType);
		checkGLSupportForParams(gl, m_params);
	}

	execute(gl);

	return STOP;
}

void ContextResetCase::execute (glw::Functions& gl)
{
	de::SharedPtr<ContextReset> contextReset					= contextResetFactory(m_params, gl, m_testCtx.getLog());
	glw::GLboolean				isContextRobust					= GL_FALSE;

	GLU_CHECK_GLW_CALL(gl, getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &isContextRobust));
	provokeReset(contextReset);

	if (m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP)
	{
		try
		{
			waitForReset(contextReset);

			const glw::GLenum	status	= gl.getGraphicsResetStatus();

			if (status == GL_NO_ERROR)
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Context was NOT lost");
			else
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "glGetGraphicsResetStatus() returned " << glu::getGraphicsResetStatusStr(status) << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was lost");
			}
		}
		catch (const glu::Error& error)
		{
			if (error.getError() == GL_CONTEXT_LOST)
				passAndLog(contextReset);
			else
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

				m_testCtx.getLog()	<< tcu::TestLog::Message
									<< "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
									<< tcu::TestLog::EndMessage;
			}
		}
	}
	else if (m_params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB || m_params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
	{
		try
		{
			waitForReset(contextReset);
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was NOT lost. Test skipped");
		}
		catch (const glu::Error& error)
		{
			if (error.getError() == GL_CONTEXT_LOST)
			{
				if (isContextRobust)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "No context reset should of occurred GL_CONTEXT_ROBUST_ACCESS == TRUE");
				else
					passAndLog(contextReset);
			}
			else if (isContextRobust)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unknown error.");
			else
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Warning: glGetError() returned wrong value. Expected GL_CONTEXT_LOST");

				m_testCtx.getLog()	<< tcu::TestLog::Message
									<< "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
									<< tcu::TestLog::EndMessage;
			}
		}
	}
	else
		DE_FATAL("Unknown context reset type");
}

class BasicResetCase : public ContextResetCase
{
public:

	BasicResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
		: ContextResetCase (eglTestCtx, name, description, params) {}

	virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Check the graphics reset status returned by glGetGraphicsResetStatus() equals "
							<< "GL_GUILTY_CONTEXT_RESET after a context reset\n\n"
							<< tcu::TestLog::EndMessage;

		contextReset->setup();
		contextReset->draw();
	}

	virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
	{
		contextReset->teardown();
		contextReset->finish();
	}

	virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
	{
		const glw::GLint status = contextReset->getGraphicsResetStatus();

		if (status == GL_NO_ERROR)
		{
			m_testCtx.getLog()	<< tcu::TestLog::Message
								<< "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getGraphicsResetStatusStr(status) << ", expected " << glu::getGraphicsResetStatusStr(GL_GUILTY_CONTEXT_RESET) << "]"
								<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
		else
		{
			if (contextReset->getError() != GL_NO_ERROR)
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error flag not reset after calling getGraphicsResetStatus()");
			else
				m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		}
	}
};

class SyncObjectResetCase : public ContextResetCase
{
public:
	SyncObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
		: ContextResetCase (eglTestCtx, name, description, params) {}

	virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Check the status of a sync object after a context reset returned by glGetSynciv() equals GL_SIGNALED\n\n"
							<< tcu::TestLog::EndMessage;

		contextReset->setup();
		contextReset->draw();
	}

	virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
	{
		contextReset->createSyncObject();
		contextReset->teardown();
		contextReset->finish();
	}

	virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
	{
		const glw::GLint status = contextReset->getSyncStatus();
		if (status != GL_SIGNALED)
		{
			m_testCtx.getLog()	<< tcu::TestLog::Message
								<< "Test failed! glGetSynciv() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_SIGNALED) << "]"
								<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
};

class QueryObjectResetCase : public ContextResetCase
{
public:
	QueryObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
		: ContextResetCase (eglTestCtx, name, description, params) {}

	virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Check the status of a query object after a context reset returned by glGetQueryObjectuiv() equals GL_TRUE\n\n"
							<< tcu::TestLog::EndMessage;

		contextReset->setup();
		contextReset->beginQuery();
		contextReset->draw();
	}

	virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
	{
		contextReset->endQuery();
		contextReset->teardown();
		contextReset->finish();
	}

	virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
	{
		const glw::GLuint queryReady = contextReset->getQueryAvailability();
		if (queryReady != GL_TRUE)
		{
			m_testCtx.getLog()	<< tcu::TestLog::Message
								<< "Test failed! glGetQueryObjectuiv() returned wrong value [" << glu::getErrorStr(queryReady) << ", expected " << glu::getErrorStr(GL_TRUE) << "]"
								<< tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		}
	}
};

class InvalidShareContextCase : public RobustnessTestCase
{
public:
	InvalidShareContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
		: RobustnessTestCase (eglTestCtx, name, description) {}

	TestCase::IterateResult	iterate	(void)
	{
		TestLog&		log		=	m_testCtx.getLog();
		const Library&	egl		=	m_eglTestCtx.getLibrary();
		bool			isOk	=	true;

		log << tcu::TestLog::Message
			<< "EGL_BAD_MATCH is generated if reset notification strategies do not match when creating shared contexts\n\n"
			<< tcu::TestLog::EndMessage;

		const EGLint attribListA[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
			EGL_NONE
		};

		const EGLint attribListB[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
			EGL_NONE
		};

		checkRequiredEGLExtensions(attribListA);

		log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
		RenderingContext contextA(m_eglTestCtx, attribListA, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);

		log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
		logAttribList(m_eglTestCtx, attribListB);

		EGLContext contextB = egl.createContext(m_eglDisplay, m_eglConfig, contextA.getContext(), attribListB);

		const EGLenum error = egl.getError();
		if (error != EGL_BAD_MATCH)
		{
			log << TestLog::Message
				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_MATCH) << "]"
				<< TestLog::EndMessage;

			isOk = false;
		}

		if (contextB != EGL_NO_CONTEXT)
			egl.destroyContext(m_eglDisplay, contextB);

		if (isOk)
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

		return STOP;
	}
};

class InvalidNotificationEnumCase : public RobustnessTestCase
{
public:
	InvalidNotificationEnumCase (EglTestContext& eglTestCtx, const char* name, const char* description)
		: RobustnessTestCase (eglTestCtx, name, description) {}

	TestCase::IterateResult	iterate	(void)
	{
		TestLog&		log		=	m_testCtx.getLog();
		const Library&	egl		=	m_eglTestCtx.getLibrary();
		bool			isOk	=	true;

		log << tcu::TestLog::Message
			<< "EGL_BAD_ATTRIBUTE is generated if EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR is used with EGL versions <= 1.4\n\n"
			<< tcu::TestLog::EndMessage;

		const EGLint attribList[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 1,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_NO_RESET_NOTIFICATION,
			EGL_NONE
		};

		if (eglu::getVersion(egl, m_eglDisplay) >= eglu::Version(1, 5))
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL version to be under 1.5");
			return STOP;
		}

		logAttribList(m_eglTestCtx, attribList);
		EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);

		const EGLenum error = egl.getError();
		if (error != EGL_BAD_ATTRIBUTE)
		{
			log << TestLog::Message
				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
				<< TestLog::EndMessage;

			isOk = false;
		}

		if (context != EGL_NO_CONTEXT)
			egl.destroyContext(m_eglDisplay, context);

		if (isOk)
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

		return STOP;
	}
};

class SharedContextResetCase : public RobustnessTestCase
{
public:
	SharedContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
		: RobustnessTestCase (eglTestCtx, name, description, params) {}

	TestCase::IterateResult	iterate	(void)
	{
		TestLog&	log		= m_testCtx.getLog();

		log << tcu::TestLog::Message
			<< "A reset in one context will result in a reset in all other contexts in its share group\n\n"
			<< tcu::TestLog::EndMessage;

		// Create two share contexts with the same reset notification strategies
		const EGLint attribListShared[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
			EGL_NONE
		};

		checkRequiredEGLExtensions(attribListShared);

		log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
		RenderingContext contextA(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);

		log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
		RenderingContext contextB(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, contextA.getContext());

		contextA.makeCurrent(m_eglSurface);

		glw::Functions gl;
		contextA.initGLFunctions(&gl, paramsToApiType(m_params));
		checkGLSupportForParams(gl, m_params);

		DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP);
		de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType()));

		contextReset->setup();
		contextReset->draw();

		try
		{
			contextReset->teardown();
			contextReset->finish();
		}
		catch (const glu::Error& error)
		{
			if (error.getError() == GL_CONTEXT_LOST)
			{
				contextB.makeCurrent(m_eglSurface);

				gl.getString(GL_VERSION); // arbitrary gl call

				if (gl.getError() != GL_CONTEXT_LOST)
				{
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context B");
					return STOP;
				}
			}
			else
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A");
				return STOP;
			}
		}

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		return STOP;
	}
};

class InvalidContextCase : public RobustnessTestCase
{
public:
	InvalidContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
		: RobustnessTestCase (eglTestCtx, name, description) {}

	TestCase::IterateResult	iterate	(void)
	{
		const Library&	egl		= m_eglTestCtx.getLibrary();
		TestLog&		log		= m_testCtx.getLog();
		bool			isOk	= true;

		log << tcu::TestLog::Message
			<< "EGL_BAD_ATTRIBUTE is generated if EXT_create_context_robustness is NOT supported but EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT is specified\n\n"
			<< tcu::TestLog::EndMessage;

		const EGLint attribList[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
			EGL_NONE
		};

		if (eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_create_context_robustness"))
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL_EXT_create_context_robustness to be unsupported");
			return STOP;
		}

		logAttribList(m_eglTestCtx, attribList);
		EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);

		const EGLenum error = egl.getError();
		if (error != EGL_BAD_ATTRIBUTE)
		{
			log << TestLog::Message
				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
				<< TestLog::EndMessage;

			isOk = false;
		}

		if (context != EGL_NO_CONTEXT)
			egl.destroyContext(m_eglDisplay, context);

		if (isOk)
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

		return STOP;
	}
};

class RecoverFromResetCase : public RobustnessTestCase
{
public:
	RecoverFromResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
		: RobustnessTestCase (eglTestCtx, name, description,  params) {}

	TestCase::IterateResult	iterate	(void)
	{
		TestLog&	log		= m_testCtx.getLog();

		log << tcu::TestLog::Message
			<< "Provoke a context reset and wait for glGetGraphicsResetStatus() to return NO_ERROR_KHR.\n"
			<< "Destroy the old context and successfully create a new context.\n\n"
			<< tcu::TestLog::EndMessage;

		const EGLint attribList[] =
		{
			EGL_CONTEXT_CLIENT_VERSION, 3,
			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
			EGL_NONE
		};

		checkRequiredEGLExtensions(attribList);

		log << tcu::TestLog::Message << "Create context A" << tcu::TestLog::EndMessage;
		RenderingContext contextA(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
		contextA.makeCurrent(m_eglSurface);

		glw::Functions gl;
		contextA.initGLFunctions(&gl, paramsToApiType(m_params));
		checkGLSupportForParams(gl, m_params);

		DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP);
		de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType()));

		contextReset->setup();
		contextReset->draw();

		try
		{
			contextReset->teardown();
			contextReset->finish();
		}
		catch (const glu::Error& error)
		{
			if (error.getError() == GL_CONTEXT_LOST)
			{
				const glw::GLint status = gl.getGraphicsResetStatus();
				if (status == GL_NO_ERROR)
				{
					log << tcu::TestLog::Message
						<< "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_GUILTY_CONTEXT_RESET) << "]"
						<< tcu::TestLog::EndMessage;

					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
					return STOP;
				}

				const int	sleepTimeMs		= 1000;				// (1 second)
				int			timeout			= sleepTimeMs * 10; // (10 seconds)
				int			reset_status	= -1;

				// wait for context to reset
				while ((reset_status = gl.getGraphicsResetStatus() != GL_NO_ERROR) && timeout > 0)
				{
					deSleep(sleepTimeMs);
					timeout -= sleepTimeMs;
				}

				if (reset_status != GL_NO_ERROR)
				{
					log	<< tcu::TestLog::Message
						<< "Test failed! Context did not reset. glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(reset_status) << ", expected " << glu::getErrorStr(GL_NO_ERROR) << "]"
						<< tcu::TestLog::EndMessage;

					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
					return STOP;
				}
			}
			else
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A");
				return STOP;
			}
		}

		try
		{
			log << tcu::TestLog::Message << "Create context B" << tcu::TestLog::EndMessage;
			RenderingContext contextB(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
		}
		catch (const glu::Error&)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! Could not create new context. glGetError() returned wrong value. Expected GL_NO_ERROR");
			return STOP;
		}

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		return STOP;
	}
};

} // anonymous

// Note: Tests limited to openGLES 3.1 contexts only
TestCaseGroup* createRobustnessTests (EglTestContext& eglTestCtx)
{
	de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "robustness", "KHR_robustness tests"));

	tcu::TestCaseGroup* const contextCreationTestGroup			= new TestCaseGroup(eglTestCtx, "create_context",						"Test valid context_creation attributes");
	tcu::TestCaseGroup* const contextResetTestGroup				= new TestCaseGroup(eglTestCtx, "reset_context",						"Test context resets scenarios");
	tcu::TestCaseGroup* const negativeContextTestGroup			= new TestCaseGroup(eglTestCtx, "negative_context",						"Test invalid context creation attributes");

	tcu::TestCaseGroup* const shadersTestGroup					= new TestCaseGroup(eglTestCtx, "shaders",								"Shader specific context reset tests");
	tcu::TestCaseGroup* const fixedFunctionTestGroup			= new TestCaseGroup(eglTestCtx, "fixed_function_pipeline",				"Fixed function pipeline context reset tests with robust context");
	tcu::TestCaseGroup* const fixedFunctionNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "fixed_function_pipeline_non_robust",	"Fixed function pipeline context reset tests with non-robust context");

	tcu::TestCaseGroup* const infiniteLoopTestGroup				= new TestCaseGroup(eglTestCtx, "infinite_loop",						"Infinite loop scenarios");
	tcu::TestCaseGroup* const outOfBoundsTestGroup				= new TestCaseGroup(eglTestCtx, "out_of_bounds",						"Out of bounds access scenarios with robust context");

	tcu::TestCaseGroup* const outOfBoundsNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "out_of_bounds_non_robust",				"Out of bounds access scenarios with non-robust context");

	const string resetScenarioDescription	= "query error states and reset notifications";
	const string syncScenarioDescription	= "query sync status with getSynciv()";
	const string queryScenarioDescription	= "check availability of query result with getQueryObjectiv()";
	const string sharedScenarioDescription	= "check reset notification is propagated to shared context";
	const string recoverScenarioDescription	= "delete the old context and create a new one";

	// infinite loop test cases
	{
		tcu::TestCaseGroup* const infiniteLoopResetTestGroup	= new TestCaseGroup(eglTestCtx, "reset_status",				"Tests that query the reset status after a context reset has occurred");
		tcu::TestCaseGroup* const infiniteLoopSyncTestGroup		= new TestCaseGroup(eglTestCtx, "sync_status",				"Tests that query the sync status after a context reset has occurred");
		tcu::TestCaseGroup* const infiniteLoopQueryTestGroup	= new TestCaseGroup(eglTestCtx, "query_status",				"Tests that query the state of a query object after a context reset has occurred");
		tcu::TestCaseGroup* const infiniteLoopSharedTestGroup	= new TestCaseGroup(eglTestCtx, "shared_context_status",	"Tests that query the state of a shared context after a reset has occurred");
		tcu::TestCaseGroup* const infiniteLoopRecoverTestGroup	= new TestCaseGroup(eglTestCtx, "recover_from_reset",		"Tests that attempt to create a new context after a context has occurred");

		static const RobustnessTestCase::Params s_infiniteLoopCases[] =
		{
			RobustnessTestCase::Params("vertex",				"Provoke a context reset in vertex shader and ",				CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_VERT),
			RobustnessTestCase::Params("fragment",				"Provoke a context reset in fragment shader and ",				CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_FRAG),
			RobustnessTestCase::Params("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_VERT_AND_FRAG),
			RobustnessTestCase::Params("compute",				"Provoke a context reset in compute shader and ",				CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_COMPUTE),
		};

		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_infiniteLoopCases); ++testNdx)
		{
			const RobustnessTestCase::Params& test = s_infiniteLoopCases[testNdx];
			infiniteLoopResetTestGroup->addChild	(new BasicResetCase				(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
			infiniteLoopSyncTestGroup->addChild		(new SyncObjectResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + syncScenarioDescription).c_str(), test));
			infiniteLoopQueryTestGroup->addChild	(new QueryObjectResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + queryScenarioDescription).c_str(), test));
			infiniteLoopSharedTestGroup->addChild	(new SharedContextResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + sharedScenarioDescription).c_str(), test));
			infiniteLoopRecoverTestGroup->addChild	(new RecoverFromResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + recoverScenarioDescription).c_str(), test));
		}

		infiniteLoopTestGroup->addChild(infiniteLoopResetTestGroup);
		infiniteLoopTestGroup->addChild(infiniteLoopSyncTestGroup);
		infiniteLoopTestGroup->addChild(infiniteLoopQueryTestGroup);
		infiniteLoopTestGroup->addChild(infiniteLoopSharedTestGroup);
		infiniteLoopTestGroup->addChild(infiniteLoopRecoverTestGroup);
	}

	// out-of-bounds test cases
	{
		// robust context
		tcu::TestCaseGroup* const uboReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
		tcu::TestCaseGroup* const uboWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
		tcu::TestCaseGroup* const ssboWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
		tcu::TestCaseGroup* const ssboReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
		tcu::TestCaseGroup* const localWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
		tcu::TestCaseGroup* const localReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");

		// non-robust context (internal use only)
		tcu::TestCaseGroup* const uboReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
		tcu::TestCaseGroup* const uboWriteArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
		tcu::TestCaseGroup* const ssboWriteArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
		tcu::TestCaseGroup* const ssboReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
		tcu::TestCaseGroup* const localWriteArrayResetNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
		tcu::TestCaseGroup* const localReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");

		static const RobustnessTestCase::Params s_outOfBoundReadCases[] =
		{
			// ubo read only
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_UBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_UBO, READWRITETYPE_READ),

			// ssbo read only
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_SSBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_SSBO, READWRITETYPE_READ),

			// local array read only
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),

			// ubo read only (non-robust)
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_UBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_UBO, READWRITETYPE_READ),

			// ssbo read only (non-robust)
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_SSBO, READWRITETYPE_READ),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_SSBO, READWRITETYPE_READ),

			// local array read only (non-robust)
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
		};

		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundReadCases); ++testNdx)
		{
			const RobustnessTestCase::Params& test = s_outOfBoundReadCases[testNdx];

			if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
				uboReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

			if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
				uboReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

			if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
				ssboReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

			if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
				ssboReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

			if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
				localReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

			if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
				localReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
		}

		static const RobustnessTestCase::Params s_outOfBoundWriteCases[] =
		{
			// ubo write only
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_UBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),

			// ssbo write only
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),

			// local array write only
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),

			// ubo write only (non-robust)
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_UBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_UBO, READWRITETYPE_WRITE),

			// ssbo write only (non-robust)
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_SSBO, READWRITETYPE_WRITE),

			// local array write only (non-robust)
			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,	RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
		};

		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundWriteCases); ++testNdx)
		{
			const RobustnessTestCase::Params& test = s_outOfBoundWriteCases[testNdx];

				if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
					uboWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

				if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
					uboWriteArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

				if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
					ssboWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

				if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
					ssboWriteArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

				if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
					localWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));

				if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
					localWriteArrayResetNonRobustTestGroup->addChild	(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
		}

		// robust Context
		tcu::TestCaseGroup* const outOfBoundsResetReadAccessTestGroup	= new TestCaseGroup(eglTestCtx, "reads",	"Out of bounds read accesses");
		tcu::TestCaseGroup* const outOfBoundsResetWriteAccessTestGroup	= new TestCaseGroup(eglTestCtx, "writes",	"Out of bounds write accesses");

		outOfBoundsResetReadAccessTestGroup->addChild(uboReadArrayResetTestGroup);
		outOfBoundsResetReadAccessTestGroup->addChild(ssboReadArrayResetTestGroup);
		outOfBoundsResetReadAccessTestGroup->addChild(localReadArrayResetTestGroup);

		outOfBoundsResetWriteAccessTestGroup->addChild(uboWriteArrayResetTestGroup);
		outOfBoundsResetWriteAccessTestGroup->addChild(ssboWriteArrayResetTestGroup);
		outOfBoundsResetWriteAccessTestGroup->addChild(localWriteArrayResetTestGroup);

		tcu::TestCaseGroup* const outOfBoundsResetTestGroup		= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");

		outOfBoundsResetTestGroup->addChild(outOfBoundsResetReadAccessTestGroup);
		outOfBoundsResetTestGroup->addChild(outOfBoundsResetWriteAccessTestGroup);

		outOfBoundsTestGroup->addChild(outOfBoundsResetTestGroup);

		// non-robust Context (internal use only)
		tcu::TestCaseGroup* const outOfBoundsResetReadAccessNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "reads",	"Out of bounds read accesses");
		tcu::TestCaseGroup* const outOfBoundsResetWriteAccessNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "writes",	"Out of bounds write accesses");

		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(uboReadArrayResetNonRobustTestGroup);
		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(ssboReadArrayResetNonRobustTestGroup);
		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(localReadArrayResetNonRobustTestGroup);

		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(uboWriteArrayResetNonRobustTestGroup);
		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(ssboWriteArrayResetNonRobustTestGroup);
		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(localWriteArrayResetNonRobustTestGroup);

		tcu::TestCaseGroup* const outOfBoundsResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");

		outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetReadAccessNonRobustTestGroup);
		outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetWriteAccessNonRobustTestGroup);

		outOfBoundsNonRobustTestGroup->addChild(outOfBoundsResetNonRobustTestGroup);
	}

	// fixed function test cases
	{
		// robust context
		tcu::TestCaseGroup* const fixedFunctionResetStatusTestGroup				= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");

		// non-robust context (internal use only)
		tcu::TestCaseGroup* const fixedFunctionResetStatusNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");

		static const RobustnessTestCase::Params s_fixedFunctionPipelineCases[] =
		{
			RobustnessTestCase::Params( "index_buffer_out_of_bounds",	"Provoke context reset and query error states and reset notifications", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES),
			RobustnessTestCase::Params( "vertex_buffer_out_of_bounds",	"Provoke context reset and query error states and reset notifications", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES),

			RobustnessTestCase::Params( "index_buffer_out_of_bounds",	"Provoke context reset and query error states and reset notifications", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES),
			RobustnessTestCase::Params( "vertex_buffer_out_of_bounds",	"Provoke context reset and query error states and reset notifications", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES),
		};

		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_fixedFunctionPipelineCases); ++testNdx)
		{
			const RobustnessTestCase::Params& test = s_fixedFunctionPipelineCases[testNdx];
			if (test.getRobustAccessType() == ROBUSTACCESS_TRUE)
				fixedFunctionResetStatusTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
			else
				fixedFunctionResetStatusNonRobustTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
		}

		fixedFunctionTestGroup->addChild(fixedFunctionResetStatusTestGroup);
		fixedFunctionNonRobustTestGroup->addChild(fixedFunctionResetStatusNonRobustTestGroup);
	}

	// context creation query cases
	{
		contextCreationTestGroup->addChild(new QueryRobustAccessCase	(eglTestCtx, "query_robust_access",		"Query robust access after successfully creating a robust context"));
		contextCreationTestGroup->addChild(new NoResetNotificationCase	(eglTestCtx, "no_reset_notification",	"Query reset notification strategy after specifying GL_NO_RESET_NOTIFICATION"));
		contextCreationTestGroup->addChild(new LoseContextOnResetCase	(eglTestCtx, "lose_context_on_reset",	"Query reset notification strategy after specifying GL_LOSE_CONTEXT_ON_RESET"));
	}

	// invalid context creation cases
	{
		negativeContextTestGroup->addChild(new InvalidContextCase			(eglTestCtx, "invalid_robust_context_creation",			"Create a non-robust context but specify a reset notification strategy"));
		negativeContextTestGroup->addChild(new InvalidShareContextCase		(eglTestCtx, "invalid_robust_shared_context_creation",	"Create a context share group with conflicting reset notification strategies"));
		negativeContextTestGroup->addChild(new InvalidNotificationEnumCase	(eglTestCtx, "invalid_notification_strategy_enum",		"Create a robust context using EGL 1.5 only enum with EGL versions <= 1.4" ));
	}

	shadersTestGroup->addChild(infiniteLoopTestGroup);
	shadersTestGroup->addChild(outOfBoundsTestGroup);
	shadersTestGroup->addChild(outOfBoundsNonRobustTestGroup);

	contextResetTestGroup->addChild(shadersTestGroup);
	contextResetTestGroup->addChild(fixedFunctionTestGroup);
	contextResetTestGroup->addChild(fixedFunctionNonRobustTestGroup);

	group->addChild(contextCreationTestGroup);
	group->addChild(contextResetTestGroup);
	group->addChild(negativeContextTestGroup);

	return group.release();
}

} // egl
} // deqp
