Home | History | Annotate | Download | only in egl
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program EGL Module
      3  * ---------------------------------------
      4  *
      5  * Copyright 2017 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Robustness tests for KHR_robustness.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "teglRobustnessTests.hpp"
     25 
     26 #include "tcuTestLog.hpp"
     27 #include "tcuStringTemplate.hpp"
     28 
     29 #include "egluConfigFilter.hpp"
     30 #include "egluStrUtil.hpp"
     31 #include "egluUtil.hpp"
     32 #include "eglwLibrary.hpp"
     33 
     34 #include "gluStrUtil.hpp"
     35 #include "gluShaderProgram.hpp"
     36 #include "gluDrawUtil.hpp"
     37 
     38 #include "glwFunctions.hpp"
     39 #include "glwEnums.hpp"
     40 
     41 #include "deSTLUtil.hpp"
     42 #include "deStringUtil.hpp"
     43 #include "deThread.hpp"
     44 #include "deSharedPtr.hpp"
     45 
     46 #include <set>
     47 
     48 using std::string;
     49 using std::vector;
     50 using std::set;
     51 using tcu::TestLog;
     52 
     53 using namespace eglw;
     54 
     55 DE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY	== 0x8256);
     56 DE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET		== 0x8252);
     57 DE_STATIC_ASSERT(GL_NO_RESET_NOTIFICATION		== 0x8261);
     58 
     59 namespace deqp
     60 {
     61 namespace egl
     62 {
     63 namespace
     64 {
     65 
     66 enum ContextResetType
     67 {
     68 	CONTEXTRESETTYPE_INFINITE_LOOP,
     69 	CONTEXTRESETTYPE_SHADER_OOB,
     70 	CONTEXTRESETTYPE_FIXED_FUNC_OOB,
     71 };
     72 
     73 enum ShaderType
     74 {
     75 	SHADERTYPE_VERT,
     76 	SHADERTYPE_FRAG,
     77 	SHADERTYPE_COMPUTE,
     78 	SHADERTYPE_VERT_AND_FRAG,
     79 };
     80 
     81 enum ReadWriteType
     82 {
     83 	READWRITETYPE_READ,
     84 	READWRITETYPE_WRITE,
     85 };
     86 
     87 enum ResourceType
     88 {
     89 	RESOURCETYPE_UBO,
     90 	RESOURCETYPE_SSBO,
     91 	RESOURCETYPE_LOCAL_ARRAY,
     92 };
     93 
     94 enum FixedFunctionType
     95 {
     96 	FIXEDFUNCTIONTYPE_INDICES,
     97 	FIXEDFUNCTIONTYPE_VERTICES,
     98 };
     99 
    100 enum RobustAccessType
    101 {
    102 	ROBUSTACCESS_TRUE,
    103 	ROBUSTACCESS_FALSE,
    104 };
    105 
    106 void requireEGLExtension (const Library& egl, EGLDisplay eglDisplay, const char* requiredExtension)
    107 {
    108 	if (!eglu::hasExtension(egl, eglDisplay, requiredExtension))
    109 		TCU_THROW(NotSupportedError, (string(requiredExtension) + " not supported").c_str());
    110 }
    111 
    112 bool isWindow (const eglu::CandidateConfig& c)
    113 {
    114 	return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
    115 }
    116 
    117 template <deUint32 Type>
    118 bool renderable (const eglu::CandidateConfig& c)
    119 {
    120 	return (c.renderableType() & Type) == Type;
    121 }
    122 
    123 eglu::ConfigFilter getRenderableFilter (deUint32 bits)
    124 {
    125 	switch (bits)
    126 	{
    127 		case EGL_OPENGL_ES2_BIT:	return renderable<EGL_OPENGL_ES2_BIT>;
    128 		case EGL_OPENGL_ES3_BIT:	return renderable<EGL_OPENGL_ES3_BIT>;
    129 		case EGL_OPENGL_BIT:		return renderable<EGL_OPENGL_BIT>;
    130 		default:
    131 			DE_FATAL("Unknown EGL bitfied value");
    132 			return renderable<0>;
    133 	}
    134 }
    135 
    136 const char* eglResetNotificationStrategyToString (EGLint strategy)
    137 {
    138 	switch (strategy)
    139 	{
    140 		case EGL_NO_RESET_NOTIFICATION_KHR:		return "EGL_NO_RESET_NOTIFICATION_KHR";
    141 		case EGL_LOSE_CONTEXT_ON_RESET_KHR:		return "EGL_LOSE_CONTEXT_ON_RESET_KHR";
    142 		default:
    143 			return "<Unknown>";
    144 	}
    145 }
    146 
    147 void logAttribList (const EglTestContext& eglTestCtx, const EGLint* attribList)
    148 {
    149 	const EGLint*		iter = &(attribList[0]);
    150 	std::ostringstream	attribListString;
    151 
    152 	while ((*iter) != EGL_NONE)
    153 	{
    154 		switch (*iter)
    155 		{
    156 		//	case EGL_CONTEXT_CLIENT_VERSION:
    157 			case EGL_CONTEXT_MAJOR_VERSION_KHR:
    158 				iter++;
    159 				attribListString << "EGL_CONTEXT_CLIENT_VERSION, " << (*iter) << ", ";
    160 				iter++;
    161 				break;
    162 
    163 			case EGL_CONTEXT_MINOR_VERSION_KHR:
    164 				iter++;
    165 				attribListString << "EGL_CONTEXT_MINOR_VERSION_KHR, " << (*iter) << ", ";
    166 				iter++;
    167 				break;
    168 
    169 			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
    170 				iter++;
    171 				attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, "
    172 								 << eglResetNotificationStrategyToString(*iter) << ", ";
    173 				iter++;
    174 				break;
    175 
    176 			case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
    177 				iter++;
    178 				attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, ";
    179 
    180 				if (*iter == EGL_FALSE || *iter == EGL_TRUE)
    181 					attribListString << (*iter ? "EGL_TRUE" : "EGL_FALSE") << ", ";
    182 				else
    183 					attribListString << (*iter) << ", ";
    184 				iter++;
    185 				break;
    186 
    187 			default:
    188 				DE_FATAL("Unsupported attribute");
    189 		}
    190 	}
    191 
    192 	attribListString << "EGL_NONE";
    193 	eglTestCtx.getTestContext().getLog() << TestLog::Message
    194 										 << "EGL attrib list: { " << attribListString.str() << " }\n\n"
    195 										 << TestLog::EndMessage;
    196 }
    197 
    198 class RobustnessTestCase: public TestCase
    199 {
    200 public:
    201 	class Params
    202 	{
    203 	public:
    204 							Params					(void) {};
    205 
    206 							Params					(const string&				name,
    207 													 const string&				description,
    208 													 const RobustAccessType&	robustAccessType,
    209 													 const ContextResetType&	contextResetType,
    210 													 const FixedFunctionType&	fixedFunctionType);
    211 
    212 							Params					(const string&				name,
    213 													 const string&				description,
    214 													 const ContextResetType&	contextResetType,
    215 													 const ShaderType&			shaderType);
    216 
    217 							Params					(const string&				name,
    218 													 const string&				description,
    219 													 const RobustAccessType&	robustAccessType,
    220 													 const ContextResetType&	contextResetType,
    221 													 const ShaderType&			shaderType,
    222 													 const ResourceType&		resourceType,
    223 													 const ReadWriteType&		readWriteType);
    224 
    225 		const string&				getName					(void) const { return m_name;				}
    226 		const string&				getDescription			(void) const { return m_description;		}
    227 		const ContextResetType&		getContextResetType		(void) const { return m_contextResetType;	}
    228 		const ShaderType&			getShaderType			(void) const { return m_shaderType;			}
    229 		const ResourceType&			getResourceType			(void) const { return m_resourceType;		}
    230 		const ReadWriteType&		getReadWriteType		(void) const { return m_readWriteType;		}
    231 		const FixedFunctionType&	getFixedFunctionType	(void) const { return m_fixedFunctionType;	}
    232 		const RobustAccessType&		getRobustAccessType		(void) const { return m_robustAccessType;	}
    233 
    234 	private:
    235 		string				m_name;
    236 		string				m_description;
    237 		RobustAccessType	m_robustAccessType;
    238 		ContextResetType	m_contextResetType;
    239 		ShaderType			m_shaderType;
    240 		ResourceType		m_resourceType;
    241 		ReadWriteType		m_readWriteType;
    242 		FixedFunctionType	m_fixedFunctionType;
    243 	};
    244 
    245 			RobustnessTestCase			(EglTestContext& eglTestCtx, const char* name, const char* description);
    246 			RobustnessTestCase			(EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
    247 			~RobustnessTestCase			(void);
    248 
    249 	void	checkRequiredEGLExtensions	(const EGLint* attribList);
    250 
    251 protected:
    252 	Params					m_params;
    253 	EGLDisplay				m_eglDisplay;
    254 	EGLConfig				m_eglConfig;
    255 	EGLSurface				m_eglSurface;
    256 
    257 private:
    258 	void					init					(void);
    259 	void					deinit					(void);
    260 	void					initEGLSurface			(void);
    261 	EGLConfig				getEGLConfig			(void);
    262 
    263 	eglu::NativeWindow*		m_window;
    264 };
    265 
    266 RobustnessTestCase::Params::Params (const string&				name,
    267 									const string&				description,
    268 									const RobustAccessType&		robustAccessType,
    269 									const ContextResetType&		contextResetType,
    270 									const FixedFunctionType&	fixedFunctionType)
    271 	: m_name				(name)
    272 	, m_description			(description)
    273 	, m_robustAccessType	(robustAccessType)
    274 	, m_contextResetType	(contextResetType)
    275 	, m_fixedFunctionType	(fixedFunctionType)
    276 {
    277 }
    278 
    279 RobustnessTestCase::Params::Params (const string&				name,
    280 									const string&				description,
    281 									const ContextResetType&		contextResetType,
    282 									const ShaderType&			shaderType)
    283 	: m_name				(name)
    284 	, m_description			(description)
    285 	, m_contextResetType	(contextResetType)
    286 	, m_shaderType			(shaderType)
    287 {
    288 }
    289 
    290 RobustnessTestCase::Params::Params (const string&				name,
    291 									const string&				description,
    292 									const RobustAccessType&		robustAccessType,
    293 									const ContextResetType&		contextResetType,
    294 									const ShaderType&			shaderType,
    295 									const ResourceType&			resourceType,
    296 									const ReadWriteType&		readWriteType)
    297 	: m_name				(name)
    298 	, m_description			(description)
    299 	, m_robustAccessType	(robustAccessType)
    300 	, m_contextResetType	(contextResetType)
    301 	, m_shaderType			(shaderType)
    302 	, m_resourceType		(resourceType)
    303 	, m_readWriteType		(readWriteType)
    304 {
    305 }
    306 
    307 RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description)
    308 	: TestCase			(eglTestCtx, name, description)
    309 	, m_eglDisplay		(EGL_NO_DISPLAY)
    310 	, m_eglConfig		(0)
    311 	, m_eglSurface		(EGL_NO_SURFACE)
    312 	, m_window			(DE_NULL)
    313 {
    314 }
    315 
    316 RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
    317 	: TestCase			(eglTestCtx, name, description)
    318 	, m_params			(params)
    319 	, m_eglDisplay		(EGL_NO_DISPLAY)
    320 	, m_eglConfig		(0)
    321 	, m_eglSurface		(EGL_NO_SURFACE)
    322 	, m_window			(DE_NULL)
    323 {
    324 }
    325 
    326 RobustnessTestCase::~RobustnessTestCase (void)
    327 {
    328 	deinit();
    329 }
    330 
    331 void RobustnessTestCase::init (void)
    332 {
    333 	m_eglDisplay	= eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
    334 	m_eglConfig		= getEGLConfig();
    335 
    336 	initEGLSurface();
    337 }
    338 
    339 void RobustnessTestCase::deinit (void)
    340 {
    341 	const Library& egl = m_eglTestCtx.getLibrary();
    342 
    343 	if (m_eglSurface != EGL_NO_SURFACE)
    344 	{
    345 		egl.destroySurface(m_eglDisplay, m_eglSurface);
    346 		m_eglSurface = EGL_NO_SURFACE;
    347 	}
    348 	if (m_eglDisplay != EGL_NO_DISPLAY)
    349 	{
    350 		egl.terminate(m_eglDisplay);
    351 		m_eglDisplay = EGL_NO_DISPLAY;
    352 	}
    353 
    354 	delete m_window;
    355 	m_window = DE_NULL;
    356 }
    357 
    358 EGLConfig RobustnessTestCase::getEGLConfig (void)
    359 {
    360 	eglu::FilterList filters;
    361 	filters << isWindow << getRenderableFilter(EGL_OPENGL_ES3_BIT);
    362 	return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, filters);
    363 }
    364 
    365 void RobustnessTestCase::initEGLSurface (void)
    366 {
    367 	EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), bindAPI(EGL_OPENGL_ES_API));
    368 
    369 	const eglu::NativeWindowFactory& factory =	eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
    370 
    371 	const eglu::WindowParams	windowParams	=	eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine()));
    372 	m_window									=	factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL, windowParams);
    373 	m_eglSurface								=	eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
    374 }
    375 
    376 glu::ApiType paramsToApiType (const RobustnessTestCase::Params& params)
    377 {
    378 	EGLint				minorVersion	= 0;
    379 	if (params.getShaderType()		 == SHADERTYPE_COMPUTE	||
    380 		params.getResourceType()	 == RESOURCETYPE_SSBO	||
    381 		params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
    382 	{
    383 		minorVersion = 1;
    384 	}
    385 
    386 	return glu::ApiType::es(3, minorVersion);
    387 }
    388 
    389 void RobustnessTestCase::checkRequiredEGLExtensions (const EGLint* attribList)
    390 {
    391 	set<string>		requiredExtensions;
    392 	vector<string>	extensions			= eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_eglDisplay);
    393 
    394 	{
    395 		const EGLint* iter = attribList;
    396 
    397 		while ((*iter) != EGL_NONE)
    398 		{
    399 			switch (*iter)
    400 			{
    401 				case EGL_CONTEXT_MAJOR_VERSION_KHR: iter++;
    402 					iter++;
    403 					break;
    404 
    405 				case EGL_CONTEXT_MINOR_VERSION_KHR:
    406 					iter++;
    407 					requiredExtensions.insert("EGL_KHR_create_context");
    408 					iter++;
    409 					break;
    410 
    411 				case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
    412 				case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
    413 					iter++;
    414 					requiredExtensions.insert("EGL_EXT_create_context_robustness");
    415 					iter++;
    416 					break;
    417 
    418 				default:
    419 					DE_ASSERT(DE_FALSE);
    420 			}
    421 		}
    422 	}
    423 
    424 	for (std::set<string>::const_iterator reqExt = requiredExtensions.begin(); reqExt != requiredExtensions.end(); ++reqExt)
    425 	{
    426 		if (!de::contains(extensions.begin(), extensions.end(), *reqExt))
    427 		{
    428 			const char* const extension = reqExt->c_str();
    429 			requireEGLExtension(m_eglTestCtx.getLibrary(), m_eglDisplay, extension);
    430 		}
    431 	}
    432 }
    433 
    434 void checkRequiredGLSupport (const glw::Functions& gl, glu::ApiType requiredApi)
    435 {
    436 	if (!glu::hasExtension(gl, requiredApi, "GL_KHR_robustness") && !glu::hasExtension(gl, requiredApi, "GL_EXT_robustness"))
    437 	{
    438 		TCU_THROW(NotSupportedError, (string("GL_KHR_robustness and GL_EXT_robustness") + " not supported").c_str());
    439 	}
    440 	else
    441 	{
    442 		int realMinorVersion = 0;
    443 		gl.getIntegerv(GL_MINOR_VERSION, &realMinorVersion);
    444 		GLU_EXPECT_NO_ERROR(gl.getError(), "Get minor version failed");
    445 
    446 		if (realMinorVersion < requiredApi.getMinorVersion())
    447 			TCU_THROW(NotSupportedError, "Test case requires GLES 3.1");
    448 	}
    449 }
    450 
    451 void checkGLSupportForParams (const glw::Functions& gl, const RobustnessTestCase::Params& params)
    452 {
    453 	int minorVersion = 0;
    454 	if (params.getShaderType()		  == SHADERTYPE_COMPUTE	||
    455 		params.getResourceType()	  == RESOURCETYPE_SSBO	||
    456 		params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
    457 	{
    458 		minorVersion = 1;
    459 	}
    460 	checkRequiredGLSupport(gl, glu::ApiType::es(3, minorVersion));
    461 }
    462 
    463 class RenderingContext
    464 {
    465 public:
    466 							RenderingContext					(const EglTestContext&	eglTestCtx,
    467 																 const EGLint*			attribList,
    468 																 const EGLConfig&		config,
    469 																 const EGLDisplay&		display,
    470 																 const EGLContext&		sharedContext);
    471 							~RenderingContext					(void);
    472 
    473 	void					initGLFunctions						(glw::Functions* gl, const glu::ApiType apiType);
    474 	void					makeCurrent							(const EGLSurface& surface);
    475 	EGLContext				getContext							(void);
    476 
    477 private:
    478 	const EglTestContext&	m_eglTestCtx;
    479 	const EGLint*			m_attribList;
    480 	const EGLConfig&		m_config;
    481 	const EGLDisplay&		m_display;
    482 	const Library&			m_egl;
    483 
    484 	EGLContext				m_context;
    485 
    486 	void					createContext						(const EGLConfig& sharedConfig);
    487 	void					destroyContext						(void);
    488 
    489 							RenderingContext					(const RenderingContext&);
    490 	RenderingContext&		operator=							(const RenderingContext&);
    491 };
    492 
    493 RenderingContext::RenderingContext (const EglTestContext&	 eglTestCtx,
    494 									const EGLint*			 attribList,
    495 									const EGLConfig&		 config,
    496 									const EGLDisplay&		 display,
    497 									const EGLContext&		 sharedContext)
    498 	: m_eglTestCtx		(eglTestCtx)
    499 	, m_attribList		(attribList)
    500 	, m_config			(config)
    501 	, m_display			(display)
    502 	, m_egl				(eglTestCtx.getLibrary())
    503 	, m_context			(EGL_NO_CONTEXT)
    504 {
    505 	logAttribList(eglTestCtx, m_attribList);
    506 	createContext(sharedContext);
    507 }
    508 
    509 RenderingContext::~RenderingContext (void)
    510 {
    511 	destroyContext();
    512 }
    513 
    514 void RenderingContext::createContext (const EGLConfig& sharedContext)
    515 {
    516 	m_context = m_egl.createContext(m_display, m_config, sharedContext, m_attribList);
    517 	EGLU_CHECK_MSG(m_egl, "eglCreateContext()");
    518 }
    519 
    520 void RenderingContext::destroyContext (void)
    521 {
    522 	EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    523 
    524 	if (m_context != EGL_NO_CONTEXT)
    525 		m_egl.destroyContext(m_display, m_context);
    526 }
    527 
    528 void RenderingContext::makeCurrent (const EGLSurface& surface)
    529 {
    530 	EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, surface, surface, m_context));
    531 }
    532 
    533 void RenderingContext::initGLFunctions (glw::Functions *gl, const glu::ApiType apiType)
    534 {
    535 	// \todo [2017-03-23 pyry] Current version has 2 somewhat ugly hacks:
    536 	//
    537 	// 1) Core functions are loaded twice. We need glGetString(i) to query supported
    538 	//    extensions to determine if we need to load EXT or KHR-suffixed robustness
    539 	//    functions. This could be fixed by exposing glw::FunctionLoader in EglTestContext
    540 	//    for example.
    541 	//
    542 	// 2) We assume that calling code will check for KHR_robustness or EXT_robustness
    543 	//    support after calling initGLFunctions(). We could move the check here.
    544 
    545 	m_eglTestCtx.initGLFunctions(gl, apiType);
    546 
    547 	{
    548 		const char* const	robustnessExt	= glu::hasExtension(*gl, apiType, "GL_KHR_robustness") ? "GL_KHR_robustness" : "GL_EXT_robustness";
    549 		const char* const	extensions[]	= { robustnessExt };
    550 
    551 		m_eglTestCtx.initGLFunctions(gl, apiType, DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
    552 	}
    553 }
    554 
    555 EGLContext RenderingContext::getContext (void)
    556 {
    557 	return m_context;
    558 }
    559 
    560 class ContextReset
    561 {
    562 public:
    563 						ContextReset				(glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
    564 						ContextReset				(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType);
    565 						ContextReset				(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);
    566 
    567 	virtual				~ContextReset				(void) {};
    568 
    569 	virtual void		setup						(void) = 0;
    570 	virtual void		draw						(void) = 0;
    571 	virtual void		teardown					(void) = 0;
    572 
    573 	void				finish						(void);
    574 	void				createSyncObject			(void);
    575 	glw::GLint			getSyncStatus				(void);
    576 
    577 	void				beginQuery					(void);
    578 	void				endQuery					(void);
    579 	glw::GLint			getError					(void);
    580 	glw::GLint			getGraphicsResetStatus		(void);
    581 	glw::GLuint			getQueryAvailability		(void);
    582 
    583 	glw::GLsync			getSyncObject				(void) const { return m_sync; }
    584 	glw::GLuint			getQueryID					(void) const { return m_queryID; }
    585 
    586 	glw::Functions&		m_gl;
    587 	tcu::TestLog&		m_log;
    588 	ShaderType			m_shaderType;
    589 	ResourceType		m_resourceType;
    590 	ReadWriteType		m_readWriteType;
    591 	FixedFunctionType	m_fixedFunctionType;
    592 
    593 private:
    594 						ContextReset				(const ContextReset&);
    595 	ContextReset&		operator=					(const ContextReset&);
    596 
    597 	glw::GLuint			m_queryID;
    598 	glw::GLsync			m_sync;
    599 };
    600 
    601 ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
    602 	: m_gl					(gl)
    603 	, m_log					(log)
    604 	, m_fixedFunctionType	(fixedFunctionType)
    605 {
    606 }
    607 
    608 ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
    609 	: m_gl				(gl)
    610 	, m_log				(log)
    611 	, m_shaderType		(shaderType)
    612 	, m_resourceType	(resourceType)
    613 	, m_readWriteType	(readWriteType)
    614 {
    615 }
    616 
    617 ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType)
    618 	: m_gl			(gl)
    619 	, m_log			(log)
    620 	, m_shaderType	(shaderType)
    621 {
    622 }
    623 
    624 void ContextReset::finish (void)
    625 {
    626 	GLU_CHECK_GLW_CALL(m_gl, finish());
    627 }
    628 
    629 void ContextReset::createSyncObject (void)
    630 {
    631 	m_sync = m_gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
    632 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFenceSync()");
    633 }
    634 
    635 glw::GLint ContextReset::getError (void)
    636 {
    637 	glw::GLint error;
    638 	error = m_gl.getError();
    639 
    640 	return error;
    641 }
    642 
    643 glw::GLint ContextReset::getGraphicsResetStatus (void)
    644 {
    645 	glw::GLint resetStatus;
    646 	resetStatus = m_gl.getGraphicsResetStatus();
    647 
    648 	return resetStatus;
    649 }
    650 
    651 glw::GLint ContextReset::getSyncStatus (void)
    652 {
    653 	glw::GLint syncStatus;
    654 	m_gl.getSynciv(m_sync, GL_SYNC_STATUS, sizeof(glw::GLint), NULL, &syncStatus);
    655 
    656 	return syncStatus;
    657 }
    658 
    659 void ContextReset::beginQuery (void)
    660 {
    661 	GLU_CHECK_GLW_CALL(m_gl, genQueries(1, &m_queryID));
    662 	GLU_CHECK_GLW_CALL(m_gl, beginQuery(GL_ANY_SAMPLES_PASSED, m_queryID));
    663 }
    664 
    665 void ContextReset::endQuery (void)
    666 {
    667 	GLU_CHECK_GLW_CALL(m_gl, endQuery(GL_ANY_SAMPLES_PASSED));
    668 }
    669 
    670 glw::GLuint ContextReset::getQueryAvailability (void)
    671 {
    672 	glw::GLuint queryReady = GL_FALSE;
    673 	m_gl.getQueryObjectuiv(m_queryID, GL_QUERY_RESULT_AVAILABLE, &queryReady);
    674 
    675 	return queryReady;
    676 }
    677 
    678 class InfiniteLoop : public ContextReset
    679 {
    680 public:
    681 						InfiniteLoop			(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType);
    682 						~InfiniteLoop			(void);
    683 
    684 	virtual void		setup					(void);
    685 	virtual void		draw					(void);
    686 	virtual void		teardown				(void);
    687 
    688 private:
    689 	glu::ProgramSources genComputeSource		(void);
    690 	glu::ProgramSources genNonComputeSource		(void);
    691 	glu::ProgramSources	genSources				(void);
    692 
    693 	glw::GLuint			m_outputBuffer;
    694 	glw::GLuint			m_coordinatesBuffer;
    695 	glw::GLint			m_coordLocation;
    696 };
    697 
    698 InfiniteLoop::InfiniteLoop (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType)
    699 	: ContextReset(gl, log, shaderType)
    700 	, m_outputBuffer		(0)
    701 	, m_coordinatesBuffer	(0)
    702 	, m_coordLocation		(0)
    703 {
    704 }
    705 
    706 InfiniteLoop::~InfiniteLoop (void)
    707 {
    708 	try
    709 	{
    710 		// Reset GL_CONTEXT_LOST error before destroying resources
    711 		m_gl.getGraphicsResetStatus();
    712 		teardown();
    713 	}
    714 	catch (...)
    715 	{
    716 		// Ignore GL errors from teardown()
    717 	}
    718 }
    719 
    720 glu::ProgramSources InfiniteLoop::genSources(void)
    721 {
    722 	if (m_shaderType == SHADERTYPE_COMPUTE)
    723 		return genComputeSource();
    724 	else
    725 		return genNonComputeSource();
    726 }
    727 
    728 glu::ProgramSources InfiniteLoop::genComputeSource(void)
    729 {
    730 	const char* const computeSource =
    731 		"#version 310 es\n"
    732 		"layout(local_size_x = 1, local_size_y = 1) in;\n"
    733 		"uniform highp int u_iterCount;\n"
    734 		"writeonly buffer Output { highp int b_output_int; };\n"
    735 		"void main ()\n"
    736 		"{\n"
    737 		"	for (highp int i = 0; i < u_iterCount || u_iterCount < 0; ++i)\n"
    738 		"		b_output_int = u_iterCount;\n"
    739 		"}\n";
    740 
    741 	return glu::ProgramSources() << glu::ComputeSource(computeSource);
    742 }
    743 
    744 glu::ProgramSources InfiniteLoop::genNonComputeSource (void)
    745 {
    746 	const bool isVertCase			= m_shaderType == SHADERTYPE_VERT;
    747 	const bool isFragCase			= m_shaderType == SHADERTYPE_FRAG;
    748 	const bool isVertAndFragment	= m_shaderType == SHADERTYPE_VERT_AND_FRAG;
    749 
    750 	std::ostringstream vert, frag;
    751 
    752 	vert << "#version 300 es\n"
    753 		 << "in highp vec2 a_position;\n";
    754 
    755 	frag << "#version 300 es\n";
    756 
    757 	vert << "uniform highp int u_iterCount;\n";
    758 	if (isFragCase || isVertAndFragment)
    759 	{
    760 		vert << "flat out highp int v_iterCount;\n";
    761 		frag << "flat in highp int v_iterCount;\n";
    762 	}
    763 
    764 	if (isVertCase || isVertAndFragment)
    765 	{
    766 		vert << "out mediump vec4 v_color;\n";
    767 		frag << "in mediump vec4 v_color;\n";
    768 	}
    769 
    770 	frag << "out mediump vec4 o_color;\n";
    771 
    772 	vert << "\nvoid main (void)\n{\n"
    773 		 << "	gl_Position = vec4(a_position, 0.0, 1.0);\n"
    774 		 << "	gl_PointSize = 1.0;\n";
    775 
    776 	if (isFragCase || isVertAndFragment)
    777 		vert << "	v_iterCount = u_iterCount;\n";
    778 
    779 	frag << "\nvoid main (void)\n{\n";
    780 
    781 	const std::string	iterCount	= (isVertCase ? "u_iterCount" : "v_iterCount");
    782 	const std::string	loopHeader	= "	for (highp int i = 0; i < " + iterCount + " || " + iterCount + " < 0; ++i)\n";
    783 	const char* const	body		= "color = cos(sin(color*1.25)*0.8);";
    784 
    785 	if (isVertAndFragment)
    786 	{
    787 		vert << "	mediump vec4 color = " << "a_position.xyxy" << ";\n";
    788 		vert << loopHeader << "		" << body << "\n";
    789 
    790 		frag << "	mediump vec4 color = " << "gl_FragCoord" << ";\n";
    791 		frag << loopHeader << "		" << body << "\n";
    792 	}
    793 	else
    794 	{
    795 		std::ostringstream&	op			= isVertCase ? vert : frag;
    796 		op << "	mediump vec4 color = " << (isVertCase ? "a_position.xyxy" : "gl_FragCoord") << ";\n";
    797 		op << loopHeader << "		" << body << "\n";
    798 	}
    799 
    800 	if (isVertCase || isVertAndFragment)
    801 	{
    802 		vert << "	v_color = color;\n";
    803 		frag << "	o_color = v_color;\n";
    804 	}
    805 	else
    806 		frag << "	o_color = color;\n";
    807 
    808 	vert << "}\n";
    809 	frag << "}\n";
    810 
    811 	return glu::ProgramSources() << glu::VertexSource(vert.str()) << glu::FragmentSource(frag.str());
    812 }
    813 
    814 void InfiniteLoop::setup (void)
    815 {
    816 	glu::ShaderProgram program (m_gl, genSources());
    817 	m_log << program;
    818 
    819 	if (!program.isOk())
    820 		TCU_FAIL("Failed to compile shader program");
    821 
    822 	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
    823 
    824 	if (m_shaderType == SHADERTYPE_COMPUTE)
    825 	{
    826 		// Output buffer setup
    827 		m_outputBuffer = 0;
    828 		GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_outputBuffer));
    829 		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, m_outputBuffer));
    830 		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), DE_NULL, GL_DYNAMIC_DRAW));
    831 		GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_outputBuffer));
    832 	}
    833 	else
    834 	{
    835 		const glw::GLfloat coords[] =
    836 		{
    837 			-1.0f, -1.0f,
    838 			+1.0f, -1.0f,
    839 			+1.0f, +1.0f,
    840 			-1.0f, +1.0f
    841 		};
    842 
    843 		m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
    844 		GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
    845 		TCU_CHECK(m_coordLocation != (glw::GLint)-1);
    846 
    847 		// Load the vertex data
    848 		m_coordinatesBuffer = 0;
    849 		GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
    850 		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
    851 		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
    852 		GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
    853 		GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
    854 	}
    855 
    856 	glw::GLint iterCountLocation = m_gl.getUniformLocation(program.getProgram(), "u_iterCount");
    857 	GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
    858 	TCU_CHECK(iterCountLocation != (glw::GLint)-1);
    859 
    860 	// Set the iteration count (infinite)
    861 	glw::GLint iterCount = -1;
    862 	GLU_CHECK_GLW_CALL(m_gl, uniform1i(iterCountLocation, iterCount));
    863 }
    864 
    865 void InfiniteLoop::draw (void)
    866 {
    867 	if (m_shaderType == SHADERTYPE_COMPUTE)
    868 		m_gl.dispatchCompute(1, 1, 1);
    869 	else
    870 	{
    871 		const glw::GLushort indices[] = { 0, 1, 2, 2, 3, 0 };
    872 		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
    873 	}
    874 }
    875 
    876 void InfiniteLoop::teardown (void)
    877 {
    878 	if (m_shaderType != SHADERTYPE_COMPUTE)
    879 	{
    880 		if (m_coordLocation)
    881 		{
    882 			GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
    883 			m_coordLocation = 0;
    884 		}
    885 	}
    886 
    887 	if (m_outputBuffer)
    888 	{
    889 		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_outputBuffer));
    890 		m_outputBuffer = 0;
    891 	}
    892 
    893 	if (m_coordinatesBuffer)
    894 	{
    895 		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
    896 		m_coordinatesBuffer = 0;
    897 	}
    898 
    899 	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
    900 }
    901 
    902 class FixedFunctionOOB : public ContextReset
    903 {
    904 public:
    905 							FixedFunctionOOB			(glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
    906 							~FixedFunctionOOB			(void);
    907 
    908 	struct TestConfig
    909 	{
    910 		int textureWidth;
    911 		int textureHeight;
    912 	};
    913 
    914 	virtual void			setup						(void);
    915 	virtual void			draw						(void);
    916 	virtual void			teardown					(void);
    917 
    918 private:
    919 	glu::ProgramSources		genSources					(void);
    920 	glw::GLuint				m_coordinatesBuffer;
    921 	glw::GLint				m_coordLocation;
    922 };
    923 
    924 FixedFunctionOOB::FixedFunctionOOB (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
    925 	: ContextReset(gl, log, fixedFunctionType)
    926 	, m_coordinatesBuffer	(0)
    927 	, m_coordLocation		(0)
    928 {
    929 }
    930 
    931 FixedFunctionOOB::~FixedFunctionOOB (void)
    932 {
    933 	try
    934 	{
    935 		// Reset GL_CONTEXT_LOST error before destroying resources
    936 		m_gl.getGraphicsResetStatus();
    937 		teardown();
    938 	}
    939 	catch (...)
    940 	{
    941 		// Ignore GL errors from teardown()
    942 	}
    943 }
    944 
    945 glu::ProgramSources FixedFunctionOOB::genSources (void)
    946 {
    947 	const char* const vert =
    948 		"#version 300 es\n"
    949 		"in highp vec4 a_position;\n"
    950 		"void main (void)\n"
    951 		"{\n"
    952 		"	gl_Position = a_position;\n"
    953 		"}\n";
    954 
    955 	const char* const frag =
    956 		"#version 300 es\n"
    957 		"layout(location = 0) out highp vec4 fragColor;\n"
    958 		"void main (void)\n"
    959 		"{\n"
    960 		"	fragColor = vec4(1.0f);\n"
    961 		"}\n";
    962 
    963 	return glu::ProgramSources() << glu::VertexSource(vert) << glu::FragmentSource(frag);
    964 }
    965 
    966 void FixedFunctionOOB::setup (void)
    967 {
    968 	glu::ShaderProgram program(m_gl, genSources());
    969 
    970 	m_log << program;
    971 
    972 	if (!program.isOk())
    973 		TCU_FAIL("Failed to compile shader program");
    974 
    975 	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
    976 
    977 	const glw::GLfloat coords[] =
    978 	{
    979 		-1.0f, -1.0f,
    980 		 1.0f, -1.0f,
    981 		 1.0f,	1.0f,
    982 		-1.0f,	1.0f
    983 	};
    984 
    985 	m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
    986 	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
    987 	TCU_CHECK(m_coordLocation != (glw::GLint)-1);
    988 
    989 	// Load the vertex data
    990 	m_coordinatesBuffer = 0;
    991 	GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
    992 	GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
    993 	GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
    994 	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
    995 	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
    996 }
    997 
    998 void FixedFunctionOOB::draw (void)
    999 {
   1000 	const glw::GLint bad_indices[] = {0, 10, 100, 1000, 10000, 100000};
   1001 
   1002 	if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_INDICES)
   1003 		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, bad_indices);
   1004 	else if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_VERTICES)
   1005 		m_gl.drawArrays(GL_TRIANGLES, 0, 1000);
   1006 	else
   1007 		DE_FATAL("Unknown fixed function type");
   1008 }
   1009 
   1010 void FixedFunctionOOB::teardown (void)
   1011 {
   1012 	if (m_coordLocation)
   1013 	{
   1014 		GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
   1015 		m_coordLocation = 0;
   1016 	}
   1017 
   1018 	if (m_coordinatesBuffer)
   1019 	{
   1020 		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
   1021 		m_coordinatesBuffer = 0;
   1022 	}
   1023 
   1024 	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
   1025 }
   1026 
   1027 class ShadersOOB : public ContextReset
   1028 {
   1029 public:
   1030 								ShadersOOB					(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);
   1031 								~ShadersOOB					(void);
   1032 
   1033 	virtual void				setup						(void);
   1034 	virtual void				draw						(void);
   1035 	virtual void				teardown					(void);
   1036 
   1037 private:
   1038 	static const int			s_numBindings				= 3;
   1039 
   1040 	glw::GLuint					m_coordinatesBuffer;
   1041 	glw::GLint					m_coordLocation;
   1042 
   1043 	bool						m_isUBO;
   1044 	bool						m_isRead;
   1045 	bool						m_isLocalArray;
   1046 	std::vector<glw::GLuint>	m_buffers;
   1047 
   1048 	std::string					genVertexShader				(const std::string& shaderDecl, const std::string& shaderBody);
   1049 	std::string					genFragmentShader			(const std::string& shaderDecl, const std::string& shaderBody);
   1050 	std::string					genComputeShader			(const std::string& shaderDecl, const std::string& shaderBody);
   1051 
   1052 	glu::ProgramSources			genNonComputeSource			(void);
   1053 	glu::ProgramSources			genComputeSource			(void);
   1054 	glu::ProgramSources			genSources					(void);
   1055 };
   1056 
   1057 ShadersOOB::ShadersOOB (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
   1058 	: ContextReset(gl, log, shaderType, resourceType, readWriteType)
   1059 	, m_coordinatesBuffer	(0)
   1060 	, m_coordLocation		(0)
   1061 	, m_buffers				(s_numBindings, 0)
   1062 {
   1063 	m_isUBO			= (m_resourceType == RESOURCETYPE_UBO);
   1064 	m_isLocalArray	= (m_resourceType == RESOURCETYPE_LOCAL_ARRAY);
   1065 	m_isRead		= (m_readWriteType == READWRITETYPE_READ);
   1066 }
   1067 
   1068 ShadersOOB::~ShadersOOB (void)
   1069 {
   1070 	try
   1071 	{
   1072 		// Reset GL_CONTEXT_LOST error before destroying resources
   1073 		m_gl.getGraphicsResetStatus();
   1074 		teardown();
   1075 	}
   1076 	catch (...)
   1077 	{
   1078 		// Ignore GL errors from teardown()
   1079 	}
   1080 }
   1081 
   1082 std::string ShadersOOB::genVertexShader (const std::string& shaderDecl, const std::string& shaderBody)
   1083 {
   1084 	static const char* const s_simpleVertexShaderSource	=
   1085 		"#version 310 es\n"
   1086 		"in highp vec4 a_position;\n"
   1087 		"void main (void)\n"
   1088 		"{\n"
   1089 		"	gl_Position = a_position;\n"
   1090 		"}\n";
   1091 
   1092 	switch (m_shaderType)
   1093 	{
   1094 		case SHADERTYPE_VERT:
   1095 		case SHADERTYPE_VERT_AND_FRAG:
   1096 		{
   1097 			std::ostringstream vertexShaderSource;
   1098 			vertexShaderSource	<<	"#version 310 es\n"
   1099 								<<	"in highp vec4 a_position;\n"
   1100 								<<	"out highp vec4 v_color;\n"
   1101 								<<	shaderDecl << "\n"
   1102 								<<	"void main (void)\n"
   1103 								<<	"{\n"
   1104 								<<	"	highp vec4 color;\n"
   1105 								<<	shaderBody << "\n"
   1106 								<<	"	v_color = color;\n"
   1107 								<<	"	gl_Position = a_position;\n"
   1108 								<<	"}\n";
   1109 
   1110 			return vertexShaderSource.str();
   1111 		}
   1112 
   1113 		case SHADERTYPE_FRAG:
   1114 			return s_simpleVertexShaderSource;
   1115 
   1116 		default:
   1117 			DE_FATAL("Unknown shader type");
   1118 			return "";
   1119 	}
   1120 }
   1121 
   1122 std::string ShadersOOB::genFragmentShader (const std::string& shaderDecl, const std::string& shaderBody)
   1123 {
   1124 	static const char* const s_simpleFragmentShaderSource =
   1125 		"#version 310 es\n"
   1126 		"in highp vec4 v_color;\n"
   1127 		"layout(location = 0) out highp vec4 fragColor;\n"
   1128 		"void main (void)\n"
   1129 		"{\n"
   1130 		"	fragColor = v_color;\n"
   1131 		"}\n";
   1132 
   1133 	switch (m_shaderType)
   1134 	{
   1135 		case SHADERTYPE_VERT:
   1136 			return s_simpleFragmentShaderSource;
   1137 
   1138 		case SHADERTYPE_FRAG:
   1139 		{
   1140 			std::ostringstream fragmentShaderSource;
   1141 			fragmentShaderSource	<<	"#version 310 es\n"
   1142 									<<	"layout(location = 0) out highp vec4 fragColor;\n"
   1143 									<<	shaderDecl << "\n"
   1144 									<<	"void main (void)\n"
   1145 									<<	"{\n"
   1146 									<<	"	highp vec4 color = vec4(0.0f);\n"
   1147 									<<	shaderBody << "\n"
   1148 									<<	"	fragColor = color;\n"
   1149 									<<	"}\n";
   1150 
   1151 			return fragmentShaderSource.str();
   1152 		}
   1153 		case SHADERTYPE_VERT_AND_FRAG:
   1154 		{
   1155 			std::ostringstream fragmentShaderSource;
   1156 			fragmentShaderSource	<<	"#version 310 es\n"
   1157 									<<	"in highp vec4 v_color;\n"
   1158 									<<	"layout(location = 0) out highp vec4 fragColor;\n"
   1159 									<<	shaderDecl << "\n"
   1160 									<<	"void main (void)\n"
   1161 									<<	"{\n"
   1162 									<<	"	highp vec4 color = vec4(0.0f);\n"
   1163 									<<	shaderBody << "\n"
   1164 									<<	"	fragColor = color;\n"
   1165 									<<	"}\n";
   1166 
   1167 			return fragmentShaderSource.str();
   1168 		}
   1169 
   1170 		default:
   1171 			DE_FATAL("Unknown shader type");
   1172 			return "";
   1173 	}
   1174 }
   1175 
   1176 std::string ShadersOOB::genComputeShader (const std::string& shaderDecl, const std::string& shaderBody)
   1177 {
   1178 	std::ostringstream computeShaderSource;
   1179 
   1180 	computeShaderSource		<<	"#version 310 es\n"
   1181 							<<	"layout(local_size_x = 1, local_size_y = 1) in;\n"
   1182 							<<	"\n"
   1183 							<<	"layout(binding = 0) buffer Output {\n"
   1184 							<<	"	highp vec4 values;\n"
   1185 							<<	"} sb_out;\n"
   1186 							<<	"\n"
   1187 							<<	shaderDecl
   1188 							<<	"void main ()\n"
   1189 							<<	"{\n"
   1190 							<<	shaderBody
   1191 							<<	"}\n";
   1192 
   1193 	return computeShaderSource.str();
   1194 }
   1195 
   1196 glu::ProgramSources ShadersOOB::genNonComputeSource (void)
   1197 {
   1198 	std::ostringstream		shaderDecl;
   1199 	std::ostringstream		shaderBody;
   1200 
   1201 	shaderDecl << "uniform highp int u_index;\n";
   1202 
   1203 	if (m_isLocalArray)
   1204 	{
   1205 		const char* const readWriteStatement = (m_isRead)
   1206 											 ? "	color.x = color_out[u_index];\n"
   1207 											 : "	color[u_index] = color_out[0];\n";
   1208 
   1209 		shaderBody	<< "	highp float color_out[4] = float[4](0.25f, 0.5f, 0.75f, 1.0f);\n"
   1210 					<< readWriteStatement;
   1211 	}
   1212 	else
   1213 	{
   1214 		const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
   1215 
   1216 		shaderDecl << "layout(std140, binding = 0) " << ((m_isUBO) ? "uniform" : "buffer") << " Block\n"
   1217 			<< "{\n"
   1218 			<< "	highp float color_out[4];\n"
   1219 			<< "} " << resName << "[" << s_numBindings << "];\n";
   1220 
   1221 		const std::string readWriteStatement = (m_isRead)
   1222 											 ? "	color.x = " + resName + "[0].color_out[u_index];\n"
   1223 											 : "	color[u_index] = " + resName + "[0].color_out[0];\n";
   1224 
   1225 		shaderBody << readWriteStatement;
   1226 	}
   1227 
   1228 	return glu::ProgramSources() << glu::VertexSource(genVertexShader(shaderDecl.str(), shaderBody.str()))
   1229 								 << glu::FragmentSource(genFragmentShader(shaderDecl.str(), shaderBody.str()));
   1230 }
   1231 
   1232 glu::ProgramSources ShadersOOB::genComputeSource (void)
   1233 {
   1234 	std::ostringstream		shaderDecl;
   1235 	std::ostringstream		shaderBody;
   1236 
   1237 	shaderDecl << "uniform highp int u_index;\n";
   1238 
   1239 	shaderBody	<< "	uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
   1240 				<< "	uint groupNdx = size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x;\n";
   1241 
   1242 	if (m_isLocalArray)
   1243 	{
   1244 		const char* const readWriteStatement = (m_isRead)
   1245 											 ? "	sb_out.values.x = values[u_index];\n"
   1246 											 : "	sb_out.values[u_index] = values.x;\n";
   1247 
   1248 		shaderBody	<< "	highp vec4 values = vec4(1.0f) * float(groupNdx);\n"
   1249 					<< readWriteStatement;
   1250 	}
   1251 	else
   1252 	{
   1253 		const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
   1254 
   1255 		shaderDecl	<< "layout(std140, binding = 1) " << ((m_isUBO) ? "uniform" : "buffer") << " Input\n"
   1256 					<< "{\n"
   1257 					<< "	highp vec4 values;\n"
   1258 					<< "} " << resName << "[" << s_numBindings << "];\n";
   1259 
   1260 		std::string readWriteStatement = (m_isRead)
   1261 									   ? "	sb_out.values.x = " + resName + "[0].values[u_index] * float(groupNdx);\n"
   1262 									   : "	sb_out.values[u_index] = " + resName + "[0].values.x * float(groupNdx);\n";
   1263 
   1264 		shaderBody << readWriteStatement;
   1265 	}
   1266 
   1267 	return glu::ProgramSources() << glu::ComputeSource(genComputeShader(shaderDecl.str(), shaderBody.str()));
   1268 }
   1269 
   1270 glu::ProgramSources ShadersOOB::genSources (void)
   1271 {
   1272 	if (m_shaderType == SHADERTYPE_COMPUTE)
   1273 		return genComputeSource();
   1274 	else
   1275 		return genNonComputeSource();
   1276 }
   1277 
   1278 void ShadersOOB::setup (void)
   1279 {
   1280 	if (!m_isUBO && !m_isLocalArray && (m_shaderType != SHADERTYPE_COMPUTE))
   1281 	{
   1282 		// Check implementation limits for shader SSBO
   1283 		int shaderStorageBlockSupported = -1;
   1284 		const bool isVertex = (m_shaderType == SHADERTYPE_VERT || m_shaderType == SHADERTYPE_VERT_AND_FRAG) ? true : false;
   1285 		string shaderTypeStr = isVertex ? "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS" : "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS";
   1286 
   1287 		GLU_CHECK_GLW_CALL(m_gl, getIntegerv(isVertex ? GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS : GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &shaderStorageBlockSupported));
   1288 
   1289 		if (shaderStorageBlockSupported < (int)m_buffers.size())
   1290 			TCU_THROW(NotSupportedError, ("Test requires " + shaderTypeStr + " >= " + de::toString((int)m_buffers.size()) + ", got " + de::toString(shaderStorageBlockSupported)).c_str());
   1291 	}
   1292 
   1293 	glu::ShaderProgram program(m_gl, genSources());
   1294 
   1295 	m_log << program;
   1296 
   1297 	if (!program.isOk())
   1298 		TCU_FAIL("Failed to compile shader program");
   1299 
   1300 	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
   1301 
   1302 	const glw::GLint indexLocation = m_gl.getUniformLocation(program.getProgram(), "u_index");
   1303 	GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
   1304 	TCU_CHECK(indexLocation != (glw::GLint)-1);
   1305 
   1306 	const glw::GLint index = -1;
   1307 	GLU_CHECK_GLW_CALL(m_gl, uniform1i(indexLocation, index));
   1308 
   1309 	if (m_shaderType != SHADERTYPE_COMPUTE)
   1310 	{
   1311 		const glw::GLfloat coords[] =
   1312 		{
   1313 			-1.0f, -1.0f,
   1314 			+1.0f, -1.0f,
   1315 			+1.0f, +1.0f,
   1316 			-1.0f, +1.0f
   1317 		};
   1318 
   1319 		// Setup vertices position
   1320 		m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
   1321 		GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
   1322 		TCU_CHECK(m_coordLocation != (glw::GLint)-1);
   1323 
   1324 		// Load the vertex data
   1325 		m_coordinatesBuffer = 0;
   1326 		GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
   1327 		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
   1328 		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
   1329 		GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
   1330 		GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
   1331 	}
   1332 
   1333 	// Create dummy data for filling buffer objects
   1334 	const std::vector<tcu::Vec4> refValues(s_numBindings, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
   1335 	glw::GLenum resType = (m_isUBO) ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER;
   1336 
   1337 	if (!m_isLocalArray)
   1338 	{
   1339 		// Set up interface block of buffer bindings
   1340 		GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
   1341 
   1342 		for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
   1343 		{
   1344 			GLU_CHECK_GLW_CALL(m_gl, bindBuffer(resType, m_buffers[bufNdx]));
   1345 			GLU_CHECK_GLW_CALL(m_gl, bufferData(resType, sizeof(tcu::Vec4), &(refValues[bufNdx]), GL_STATIC_DRAW));
   1346 			GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(resType, bufNdx, m_buffers[bufNdx]));
   1347 		}
   1348 	}
   1349 }
   1350 
   1351 void ShadersOOB::draw (void)
   1352 {
   1353 	if (m_shaderType == SHADERTYPE_COMPUTE)
   1354 		m_gl.dispatchCompute(1, 1, 1);
   1355 	else
   1356 	{
   1357 		const glw::GLuint indices[] = {0, 1, 2, 2, 3, 0};
   1358 		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
   1359 	}
   1360 }
   1361 
   1362 void ShadersOOB::teardown (void)
   1363 {
   1364 	if (m_shaderType != SHADERTYPE_COMPUTE)
   1365 	{
   1366 		if (m_coordLocation)
   1367 		{
   1368 			GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
   1369 			m_coordLocation = 0;
   1370 		}
   1371 	}
   1372 
   1373 	if (m_coordinatesBuffer)
   1374 	{
   1375 		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
   1376 		m_coordinatesBuffer = 0;
   1377 	}
   1378 
   1379 	if (!m_isLocalArray)
   1380 	{
   1381 		if (!m_buffers.empty())
   1382 		{
   1383 			GLU_CHECK_GLW_CALL(m_gl, deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
   1384 			m_buffers.clear();
   1385 		}
   1386 	}
   1387 
   1388 	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
   1389 }
   1390 
   1391 class QueryRobustAccessCase : public RobustnessTestCase
   1392 {
   1393 public:
   1394 	QueryRobustAccessCase (EglTestContext& eglTestCtx, const char* name, const char* description)
   1395 		: RobustnessTestCase (eglTestCtx, name, description) {}
   1396 
   1397 	TestCase::IterateResult	iterate		(void)
   1398 	{
   1399 		TestLog&	log		= m_testCtx.getLog();
   1400 
   1401 		log << tcu::TestLog::Message
   1402 			<< "Check that after successfully creating a robust context the robust access query returned by glBooleanv() equals GL_TRUE\n\n"
   1403 			<< tcu::TestLog::EndMessage;
   1404 
   1405 		const EGLint attribList[] =
   1406 		{
   1407 			EGL_CONTEXT_CLIENT_VERSION, 3,
   1408 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1409 			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
   1410 			EGL_NONE
   1411 		};
   1412 
   1413 		checkRequiredEGLExtensions(attribList);
   1414 
   1415 		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   1416 		context.makeCurrent(m_eglSurface);
   1417 
   1418 		glw::Functions gl;
   1419 		{
   1420 			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
   1421 			context.initGLFunctions(&gl, apiType);
   1422 			checkRequiredGLSupport(gl, apiType);
   1423 		}
   1424 
   1425 		deUint8 robustAccessGL;
   1426 		gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
   1427 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
   1428 
   1429 		if (robustAccessGL != GL_TRUE)
   1430 		{
   1431 			log << TestLog::Message
   1432 				<< "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '" << robustAccessGL << "' expected GL_TRUE."
   1433 				<< TestLog::EndMessage;
   1434 
   1435 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1436 			return STOP;
   1437 		}
   1438 
   1439 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1440 		return STOP;
   1441 	}
   1442 };
   1443 
   1444 class NoResetNotificationCase : public RobustnessTestCase
   1445 {
   1446 public:
   1447 	NoResetNotificationCase (EglTestContext& eglTestCtx, const char* name, const char* description)
   1448 		: RobustnessTestCase (eglTestCtx, name, description) {}
   1449 
   1450 	TestCase::IterateResult	iterate		(void)
   1451 	{
   1452 		TestLog&	log		= m_testCtx.getLog();
   1453 
   1454 		log << tcu::TestLog::Message
   1455 			<< "Check the reset notification strategy returned by glGetIntegerv() equals GL_NO_RESET_NOTIFICATION\n\n"
   1456 			<< tcu::TestLog::EndMessage;
   1457 
   1458 		const EGLint attribList[] =
   1459 		{
   1460 			EGL_CONTEXT_CLIENT_VERSION, 3,
   1461 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1462 			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
   1463 			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
   1464 			EGL_NONE
   1465 		};
   1466 
   1467 		checkRequiredEGLExtensions(attribList);
   1468 
   1469 		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   1470 		context.makeCurrent(m_eglSurface);
   1471 
   1472 		glw::Functions gl;
   1473 		{
   1474 			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
   1475 			context.initGLFunctions(&gl, apiType);
   1476 			checkRequiredGLSupport(gl, apiType);
   1477 		}
   1478 
   1479 		deUint8 robustAccessGL;
   1480 		gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
   1481 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
   1482 
   1483 		glw::GLint reset = 0;
   1484 		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
   1485 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
   1486 
   1487 		if (reset != GL_NO_RESET_NOTIFICATION)
   1488 		{
   1489 			log	<< tcu::TestLog::Message
   1490 				<< "Test failed! glGetIntegerv() returned wrong value. [" << glu::getErrorStr(reset) << ", expected " << glu::getErrorStr(GL_NO_RESET_NOTIFICATION) << "]"
   1491 				<< tcu::TestLog::EndMessage;
   1492 
   1493 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1494 			return STOP;
   1495 		}
   1496 
   1497 		GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
   1498 
   1499 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1500 		return STOP;
   1501 	}
   1502 };
   1503 
   1504 class LoseContextOnResetCase : public RobustnessTestCase
   1505 {
   1506 public:
   1507 	LoseContextOnResetCase (EglTestContext& eglTestCtx, const char* name, const char* description)
   1508 		: RobustnessTestCase(eglTestCtx, name, description) {}
   1509 
   1510 	TestCase::IterateResult	iterate		(void)
   1511 	{
   1512 		TestLog&	log		= m_testCtx.getLog();
   1513 
   1514 		log << tcu::TestLog::Message
   1515 			<< "Check the reset notification strategy returned by glGetIntegerv() equals GL_LOSE_CONTEXT_ON_RESET\n\n"
   1516 			<< tcu::TestLog::EndMessage;
   1517 
   1518 		const EGLint attribList[] =
   1519 		{
   1520 			EGL_CONTEXT_CLIENT_VERSION, 3,
   1521 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1522 			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
   1523 			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
   1524 			EGL_NONE
   1525 		};
   1526 
   1527 		checkRequiredEGLExtensions(attribList);
   1528 
   1529 		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   1530 		context.makeCurrent(m_eglSurface);
   1531 
   1532 		glw::Functions gl;
   1533 		{
   1534 			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
   1535 			context.initGLFunctions(&gl, apiType);
   1536 			checkRequiredGLSupport(gl, apiType);
   1537 		}
   1538 		glw::GLint reset = 0;
   1539 		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
   1540 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
   1541 
   1542 		if (reset != GL_LOSE_CONTEXT_ON_RESET)
   1543 		{
   1544 			log	<< tcu::TestLog::Message
   1545 				<< "Test failed! glGetIntegerv() returned wrong value. [" << reset << ", expected " << glu::getErrorStr(GL_LOSE_CONTEXT_ON_RESET) << "]"
   1546 				<< tcu::TestLog::EndMessage;
   1547 
   1548 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1549 			return STOP;
   1550 		}
   1551 
   1552 		log << tcu::TestLog::Message
   1553 			<< "Check the graphics reset status returned by glGetGraphicsResetStatus() "
   1554 			<< "equals GL_NO_ERROR\n"
   1555 			<< tcu::TestLog::EndMessage;
   1556 
   1557 		GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
   1558 
   1559 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1560 		return STOP;
   1561 	}
   1562 };
   1563 
   1564 de::SharedPtr<ContextReset> contextResetFactory (const RobustnessTestCase::Params params, glw::Functions& gl, tcu::TestLog& log)
   1565 {
   1566 	if (params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP)
   1567 		return de::SharedPtr<ContextReset>(new InfiniteLoop(gl, log, params.getShaderType()));
   1568 
   1569 	if (params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
   1570 		return de::SharedPtr<ContextReset>(new FixedFunctionOOB(gl, log, params.getFixedFunctionType()));
   1571 
   1572 	if (params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
   1573 		return de::SharedPtr<ContextReset>(new ShadersOOB(gl, log, params.getShaderType(), params.getResourceType(), params.getReadWriteType()));
   1574 	else
   1575 	{
   1576 		DE_FATAL("Unknown context reset type");
   1577 		return de::SharedPtr<ContextReset>(DE_NULL);
   1578 	}
   1579 }
   1580 
   1581 class ContextResetCase : public RobustnessTestCase
   1582 {
   1583 
   1584 public:
   1585 							ContextResetCase		(EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
   1586 	virtual					~ContextResetCase		(void) {};
   1587 
   1588 	virtual void			provokeReset			(de::SharedPtr<ContextReset>& contextReset) = 0;
   1589 	virtual void			waitForReset			(de::SharedPtr<ContextReset>& contextReset) = 0;
   1590 	virtual void			passAndLog				(de::SharedPtr<ContextReset>& contextReset) = 0;
   1591 
   1592 	TestCase::IterateResult iterate					(void);
   1593 	void					execute					(glw::Functions& gl);
   1594 
   1595 private:
   1596 						ContextResetCase			(const ContextResetCase&);
   1597 	ContextResetCase&	operator=					(const ContextResetCase&);
   1598 };
   1599 
   1600 ContextResetCase::ContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
   1601 	: RobustnessTestCase (eglTestCtx, name, description, params) {}
   1602 
   1603 TestCase::IterateResult ContextResetCase::iterate (void)
   1604 {
   1605 	glw::Functions	gl;
   1606 
   1607 	const EGLint attribList[] =
   1608 	{
   1609 		EGL_CONTEXT_CLIENT_VERSION, 3,
   1610 		EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1611 		EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, (m_params.getRobustAccessType() == ROBUSTACCESS_TRUE) ? EGL_TRUE : EGL_FALSE,
   1612 		EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
   1613 		EGL_NONE
   1614 	};
   1615 
   1616 	checkRequiredEGLExtensions(attribList);
   1617 
   1618 	RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   1619 	context.makeCurrent(m_eglSurface);
   1620 
   1621 	{
   1622 		const glu::ApiType apiType = paramsToApiType(m_params);
   1623 		context.initGLFunctions(&gl, apiType);
   1624 		checkGLSupportForParams(gl, m_params);
   1625 	}
   1626 
   1627 	execute(gl);
   1628 
   1629 	return STOP;
   1630 }
   1631 
   1632 void ContextResetCase::execute (glw::Functions& gl)
   1633 {
   1634 	de::SharedPtr<ContextReset> contextReset					= contextResetFactory(m_params, gl, m_testCtx.getLog());
   1635 	glw::GLboolean				isContextRobust					= GL_FALSE;
   1636 
   1637 	GLU_CHECK_GLW_CALL(gl, getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &isContextRobust));
   1638 	provokeReset(contextReset);
   1639 
   1640 	if (m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP)
   1641 	{
   1642 		try
   1643 		{
   1644 			waitForReset(contextReset);
   1645 
   1646 			const glw::GLenum	status	= gl.getGraphicsResetStatus();
   1647 
   1648 			if (status == GL_NO_ERROR)
   1649 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Context was NOT lost");
   1650 			else
   1651 			{
   1652 				m_testCtx.getLog() << tcu::TestLog::Message << "glGetGraphicsResetStatus() returned " << glu::getGraphicsResetStatusStr(status) << tcu::TestLog::EndMessage;
   1653 				m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was lost");
   1654 			}
   1655 		}
   1656 		catch (const glu::Error& error)
   1657 		{
   1658 			if (error.getError() == GL_CONTEXT_LOST)
   1659 				passAndLog(contextReset);
   1660 			else
   1661 			{
   1662 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1663 
   1664 				m_testCtx.getLog()	<< tcu::TestLog::Message
   1665 									<< "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
   1666 									<< tcu::TestLog::EndMessage;
   1667 			}
   1668 		}
   1669 	}
   1670 	else if (m_params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB || m_params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
   1671 	{
   1672 		try
   1673 		{
   1674 			waitForReset(contextReset);
   1675 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was NOT lost. Test skipped");
   1676 		}
   1677 		catch (const glu::Error& error)
   1678 		{
   1679 			if (error.getError() == GL_CONTEXT_LOST)
   1680 			{
   1681 				if (isContextRobust)
   1682 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "No context reset should of occurred GL_CONTEXT_ROBUST_ACCESS == TRUE");
   1683 				else
   1684 					passAndLog(contextReset);
   1685 			}
   1686 			else if (isContextRobust)
   1687 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unknown error.");
   1688 			else
   1689 			{
   1690 				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Warning: glGetError() returned wrong value. Expected GL_CONTEXT_LOST");
   1691 
   1692 				m_testCtx.getLog()	<< tcu::TestLog::Message
   1693 									<< "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
   1694 									<< tcu::TestLog::EndMessage;
   1695 			}
   1696 		}
   1697 	}
   1698 	else
   1699 		DE_FATAL("Unknown context reset type");
   1700 }
   1701 
   1702 class BasicResetCase : public ContextResetCase
   1703 {
   1704 public:
   1705 
   1706 	BasicResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
   1707 		: ContextResetCase (eglTestCtx, name, description, params) {}
   1708 
   1709 	virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
   1710 	{
   1711 		m_testCtx.getLog()	<< tcu::TestLog::Message
   1712 							<< "Check the graphics reset status returned by glGetGraphicsResetStatus() equals "
   1713 							<< "GL_GUILTY_CONTEXT_RESET after a context reset\n\n"
   1714 							<< tcu::TestLog::EndMessage;
   1715 
   1716 		contextReset->setup();
   1717 		contextReset->draw();
   1718 	}
   1719 
   1720 	virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
   1721 	{
   1722 		contextReset->teardown();
   1723 		contextReset->finish();
   1724 	}
   1725 
   1726 	virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
   1727 	{
   1728 		const glw::GLint status = contextReset->getGraphicsResetStatus();
   1729 
   1730 		if (status == GL_NO_ERROR)
   1731 		{
   1732 			m_testCtx.getLog()	<< tcu::TestLog::Message
   1733 								<< "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getGraphicsResetStatusStr(status) << ", expected " << glu::getGraphicsResetStatusStr(GL_GUILTY_CONTEXT_RESET) << "]"
   1734 								<< tcu::TestLog::EndMessage;
   1735 
   1736 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1737 		}
   1738 		else
   1739 		{
   1740 			if (contextReset->getError() != GL_NO_ERROR)
   1741 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error flag not reset after calling getGraphicsResetStatus()");
   1742 			else
   1743 				m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1744 		}
   1745 	}
   1746 };
   1747 
   1748 class SyncObjectResetCase : public ContextResetCase
   1749 {
   1750 public:
   1751 	SyncObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
   1752 		: ContextResetCase (eglTestCtx, name, description, params) {}
   1753 
   1754 	virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
   1755 	{
   1756 		m_testCtx.getLog()	<< tcu::TestLog::Message
   1757 							<< "Check the status of a sync object after a context reset returned by glGetSynciv() equals GL_SIGNALED\n\n"
   1758 							<< tcu::TestLog::EndMessage;
   1759 
   1760 		contextReset->setup();
   1761 		contextReset->draw();
   1762 	}
   1763 
   1764 	virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
   1765 	{
   1766 		contextReset->createSyncObject();
   1767 		contextReset->teardown();
   1768 		contextReset->finish();
   1769 	}
   1770 
   1771 	virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
   1772 	{
   1773 		const glw::GLint status = contextReset->getSyncStatus();
   1774 		if (status != GL_SIGNALED)
   1775 		{
   1776 			m_testCtx.getLog()	<< tcu::TestLog::Message
   1777 								<< "Test failed! glGetSynciv() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_SIGNALED) << "]"
   1778 								<< tcu::TestLog::EndMessage;
   1779 
   1780 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1781 		}
   1782 		else
   1783 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1784 	}
   1785 };
   1786 
   1787 class QueryObjectResetCase : public ContextResetCase
   1788 {
   1789 public:
   1790 	QueryObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
   1791 		: ContextResetCase (eglTestCtx, name, description, params) {}
   1792 
   1793 	virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
   1794 	{
   1795 		m_testCtx.getLog()	<< tcu::TestLog::Message
   1796 							<< "Check the status of a query object after a context reset returned by glGetQueryObjectuiv() equals GL_TRUE\n\n"
   1797 							<< tcu::TestLog::EndMessage;
   1798 
   1799 		contextReset->setup();
   1800 		contextReset->beginQuery();
   1801 		contextReset->draw();
   1802 	}
   1803 
   1804 	virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
   1805 	{
   1806 		contextReset->endQuery();
   1807 		contextReset->teardown();
   1808 		contextReset->finish();
   1809 	}
   1810 
   1811 	virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
   1812 	{
   1813 		const glw::GLuint queryReady = contextReset->getQueryAvailability();
   1814 		if (queryReady != GL_TRUE)
   1815 		{
   1816 			m_testCtx.getLog()	<< tcu::TestLog::Message
   1817 								<< "Test failed! glGetQueryObjectuiv() returned wrong value [" << glu::getErrorStr(queryReady) << ", expected " << glu::getErrorStr(GL_TRUE) << "]"
   1818 								<< tcu::TestLog::EndMessage;
   1819 
   1820 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1821 		}
   1822 		else
   1823 		{
   1824 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1825 		}
   1826 	}
   1827 };
   1828 
   1829 class InvalidShareContextCase : public RobustnessTestCase
   1830 {
   1831 public:
   1832 	InvalidShareContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
   1833 		: RobustnessTestCase (eglTestCtx, name, description) {}
   1834 
   1835 	TestCase::IterateResult	iterate	(void)
   1836 	{
   1837 		TestLog&		log		=	m_testCtx.getLog();
   1838 		const Library&	egl		=	m_eglTestCtx.getLibrary();
   1839 		bool			isOk	=	true;
   1840 
   1841 		log << tcu::TestLog::Message
   1842 			<< "EGL_BAD_MATCH is generated if reset notification strategies do not match when creating shared contexts\n\n"
   1843 			<< tcu::TestLog::EndMessage;
   1844 
   1845 		const EGLint attribListA[] =
   1846 		{
   1847 			EGL_CONTEXT_CLIENT_VERSION, 3,
   1848 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1849 			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
   1850 			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
   1851 			EGL_NONE
   1852 		};
   1853 
   1854 		const EGLint attribListB[] =
   1855 		{
   1856 			EGL_CONTEXT_CLIENT_VERSION, 3,
   1857 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1858 			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
   1859 			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
   1860 			EGL_NONE
   1861 		};
   1862 
   1863 		checkRequiredEGLExtensions(attribListA);
   1864 
   1865 		log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
   1866 		RenderingContext contextA(m_eglTestCtx, attribListA, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   1867 
   1868 		log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
   1869 		logAttribList(m_eglTestCtx, attribListB);
   1870 
   1871 		EGLContext contextB = egl.createContext(m_eglDisplay, m_eglConfig, contextA.getContext(), attribListB);
   1872 
   1873 		const EGLenum error = egl.getError();
   1874 		if (error != EGL_BAD_MATCH)
   1875 		{
   1876 			log << TestLog::Message
   1877 				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_MATCH) << "]"
   1878 				<< TestLog::EndMessage;
   1879 
   1880 			isOk = false;
   1881 		}
   1882 
   1883 		if (contextB != EGL_NO_CONTEXT)
   1884 			egl.destroyContext(m_eglDisplay, contextB);
   1885 
   1886 		if (isOk)
   1887 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1888 		else
   1889 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1890 
   1891 		return STOP;
   1892 	}
   1893 };
   1894 
   1895 class SharedContextResetCase : public RobustnessTestCase
   1896 {
   1897 public:
   1898 	SharedContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
   1899 		: RobustnessTestCase (eglTestCtx, name, description, params) {}
   1900 
   1901 	TestCase::IterateResult	iterate	(void)
   1902 	{
   1903 		TestLog&	log		= m_testCtx.getLog();
   1904 
   1905 		log << tcu::TestLog::Message
   1906 			<< "A reset in one context will result in a reset in all other contexts in its share group\n\n"
   1907 			<< tcu::TestLog::EndMessage;
   1908 
   1909 		// Create two share contexts with the same reset notification strategies
   1910 		const EGLint attribListShared[] =
   1911 		{
   1912 			EGL_CONTEXT_CLIENT_VERSION, 3,
   1913 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1914 			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
   1915 			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
   1916 			EGL_NONE
   1917 		};
   1918 
   1919 		checkRequiredEGLExtensions(attribListShared);
   1920 
   1921 		log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
   1922 		RenderingContext contextA(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   1923 
   1924 		log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
   1925 		RenderingContext contextB(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, contextA.getContext());
   1926 
   1927 		contextA.makeCurrent(m_eglSurface);
   1928 
   1929 		glw::Functions gl;
   1930 		contextA.initGLFunctions(&gl, paramsToApiType(m_params));
   1931 		checkGLSupportForParams(gl, m_params);
   1932 
   1933 		DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP);
   1934 		de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType()));
   1935 
   1936 		contextReset->setup();
   1937 		contextReset->draw();
   1938 
   1939 		try
   1940 		{
   1941 			contextReset->teardown();
   1942 			contextReset->finish();
   1943 		}
   1944 		catch (const glu::Error& error)
   1945 		{
   1946 			if (error.getError() == GL_CONTEXT_LOST)
   1947 			{
   1948 				contextB.makeCurrent(m_eglSurface);
   1949 
   1950 				gl.getString(GL_VERSION); // arbitrary gl call
   1951 
   1952 				if (gl.getError() != GL_CONTEXT_LOST)
   1953 				{
   1954 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context B");
   1955 					return STOP;
   1956 				}
   1957 			}
   1958 			else
   1959 			{
   1960 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A");
   1961 				return STOP;
   1962 			}
   1963 		}
   1964 
   1965 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1966 		return STOP;
   1967 	}
   1968 };
   1969 
   1970 class InvalidContextCase : public RobustnessTestCase
   1971 {
   1972 public:
   1973 	InvalidContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
   1974 		: RobustnessTestCase (eglTestCtx, name, description) {}
   1975 
   1976 	TestCase::IterateResult	iterate	(void)
   1977 	{
   1978 		const Library&	egl		= m_eglTestCtx.getLibrary();
   1979 		TestLog&		log		= m_testCtx.getLog();
   1980 		bool			isOk	= true;
   1981 
   1982 		log << tcu::TestLog::Message
   1983 			<< "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"
   1984 			<< tcu::TestLog::EndMessage;
   1985 
   1986 		const EGLint attribList[] =
   1987 		{
   1988 			EGL_CONTEXT_CLIENT_VERSION, 3,
   1989 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   1990 			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
   1991 			EGL_NONE
   1992 		};
   1993 
   1994 		if (eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_create_context_robustness"))
   1995 		{
   1996 			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL_EXT_create_context_robustness to be unsupported");
   1997 			return STOP;
   1998 		}
   1999 
   2000 		logAttribList(m_eglTestCtx, attribList);
   2001 		EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
   2002 
   2003 		const EGLenum error = egl.getError();
   2004 		if (error != EGL_BAD_ATTRIBUTE)
   2005 		{
   2006 			log << TestLog::Message
   2007 				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
   2008 				<< TestLog::EndMessage;
   2009 
   2010 			isOk = false;
   2011 		}
   2012 
   2013 		if (context != EGL_NO_CONTEXT)
   2014 			egl.destroyContext(m_eglDisplay, context);
   2015 
   2016 		if (isOk)
   2017 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2018 		else
   2019 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2020 
   2021 		return STOP;
   2022 	}
   2023 };
   2024 
   2025 class RecoverFromResetCase : public RobustnessTestCase
   2026 {
   2027 public:
   2028 	RecoverFromResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
   2029 		: RobustnessTestCase (eglTestCtx, name, description,  params) {}
   2030 
   2031 	TestCase::IterateResult	iterate	(void)
   2032 	{
   2033 		TestLog&	log		= m_testCtx.getLog();
   2034 
   2035 		log << tcu::TestLog::Message
   2036 			<< "Provoke a context reset and wait for glGetGraphicsResetStatus() to return NO_ERROR_KHR.\n"
   2037 			<< "Destroy the old context and successfully create a new context.\n\n"
   2038 			<< tcu::TestLog::EndMessage;
   2039 
   2040 		const EGLint attribList[] =
   2041 		{
   2042 			EGL_CONTEXT_CLIENT_VERSION, 3,
   2043 			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
   2044 			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
   2045 			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
   2046 			EGL_NONE
   2047 		};
   2048 
   2049 		checkRequiredEGLExtensions(attribList);
   2050 
   2051 		log << tcu::TestLog::Message << "Create context A" << tcu::TestLog::EndMessage;
   2052 		RenderingContext contextA(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   2053 		contextA.makeCurrent(m_eglSurface);
   2054 
   2055 		glw::Functions gl;
   2056 		contextA.initGLFunctions(&gl, paramsToApiType(m_params));
   2057 		checkGLSupportForParams(gl, m_params);
   2058 
   2059 		DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP);
   2060 		de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType()));
   2061 
   2062 		contextReset->setup();
   2063 		contextReset->draw();
   2064 
   2065 		try
   2066 		{
   2067 			contextReset->teardown();
   2068 			contextReset->finish();
   2069 		}
   2070 		catch (const glu::Error& error)
   2071 		{
   2072 			if (error.getError() == GL_CONTEXT_LOST)
   2073 			{
   2074 				const glw::GLint status = gl.getGraphicsResetStatus();
   2075 				if (status == GL_NO_ERROR)
   2076 				{
   2077 					log << tcu::TestLog::Message
   2078 						<< "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_GUILTY_CONTEXT_RESET) << "]"
   2079 						<< tcu::TestLog::EndMessage;
   2080 
   2081 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2082 					return STOP;
   2083 				}
   2084 
   2085 				const int	sleepTimeMs		= 1000;				// (1 second)
   2086 				int			timeout			= sleepTimeMs * 10; // (10 seconds)
   2087 				int			reset_status	= -1;
   2088 
   2089 				// wait for context to reset
   2090 				while ((reset_status = gl.getGraphicsResetStatus() != GL_NO_ERROR) && timeout > 0)
   2091 				{
   2092 					deSleep(sleepTimeMs);
   2093 					timeout -= sleepTimeMs;
   2094 				}
   2095 
   2096 				if (reset_status != GL_NO_ERROR)
   2097 				{
   2098 					log	<< tcu::TestLog::Message
   2099 						<< "Test failed! Context did not reset. glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(reset_status) << ", expected " << glu::getErrorStr(GL_NO_ERROR) << "]"
   2100 						<< tcu::TestLog::EndMessage;
   2101 
   2102 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2103 					return STOP;
   2104 				}
   2105 			}
   2106 			else
   2107 			{
   2108 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A");
   2109 				return STOP;
   2110 			}
   2111 		}
   2112 
   2113 		try
   2114 		{
   2115 			log << tcu::TestLog::Message << "Create context B" << tcu::TestLog::EndMessage;
   2116 			RenderingContext contextB(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
   2117 		}
   2118 		catch (const glu::Error&)
   2119 		{
   2120 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! Could not create new context. glGetError() returned wrong value. Expected GL_NO_ERROR");
   2121 			return STOP;
   2122 		}
   2123 
   2124 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2125 		return STOP;
   2126 	}
   2127 };
   2128 
   2129 } // anonymous
   2130 
   2131 // Note: Tests limited to openGLES 3.1 contexts only
   2132 TestCaseGroup* createRobustnessTests (EglTestContext& eglTestCtx)
   2133 {
   2134 	de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "robustness", "KHR_robustness tests"));
   2135 
   2136 	tcu::TestCaseGroup* const contextCreationTestGroup			= new TestCaseGroup(eglTestCtx, "create_context",						"Test valid context_creation attributes");
   2137 	tcu::TestCaseGroup* const contextResetTestGroup				= new TestCaseGroup(eglTestCtx, "reset_context",						"Test context resets scenarios");
   2138 	tcu::TestCaseGroup* const negativeContextTestGroup			= new TestCaseGroup(eglTestCtx, "negative_context",						"Test invalid context creation attributes");
   2139 
   2140 	tcu::TestCaseGroup* const shadersTestGroup					= new TestCaseGroup(eglTestCtx, "shaders",								"Shader specific context reset tests");
   2141 	tcu::TestCaseGroup* const fixedFunctionTestGroup			= new TestCaseGroup(eglTestCtx, "fixed_function_pipeline",				"Fixed function pipeline context reset tests with robust context");
   2142 	tcu::TestCaseGroup* const fixedFunctionNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "fixed_function_pipeline_non_robust",	"Fixed function pipeline context reset tests with non-robust context");
   2143 
   2144 	tcu::TestCaseGroup* const infiniteLoopTestGroup				= new TestCaseGroup(eglTestCtx, "infinite_loop",						"Infinite loop scenarios");
   2145 	tcu::TestCaseGroup* const outOfBoundsTestGroup				= new TestCaseGroup(eglTestCtx, "out_of_bounds",						"Out of bounds access scenarios with robust context");
   2146 
   2147 	tcu::TestCaseGroup* const outOfBoundsNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "out_of_bounds_non_robust",				"Out of bounds access scenarios with non-robust context");
   2148 
   2149 	const string resetScenarioDescription	= "query error states and reset notifications";
   2150 	const string syncScenarioDescription	= "query sync status with getSynciv()";
   2151 	const string queryScenarioDescription	= "check availability of query result with getQueryObjectiv()";
   2152 	const string sharedScenarioDescription	= "check reset notification is propagated to shared context";
   2153 	const string recoverScenarioDescription	= "delete the old context and create a new one";
   2154 
   2155 	// infinite loop test cases
   2156 	{
   2157 		tcu::TestCaseGroup* const infiniteLoopResetTestGroup	= new TestCaseGroup(eglTestCtx, "reset_status",				"Tests that query the reset status after a context reset has occurred");
   2158 		tcu::TestCaseGroup* const infiniteLoopSyncTestGroup		= new TestCaseGroup(eglTestCtx, "sync_status",				"Tests that query the sync status after a context reset has occurred");
   2159 		tcu::TestCaseGroup* const infiniteLoopQueryTestGroup	= new TestCaseGroup(eglTestCtx, "query_status",				"Tests that query the state of a query object after a context reset has occurred");
   2160 		tcu::TestCaseGroup* const infiniteLoopSharedTestGroup	= new TestCaseGroup(eglTestCtx, "shared_context_status",	"Tests that query the state of a shared context after a reset has occurred");
   2161 		tcu::TestCaseGroup* const infiniteLoopRecoverTestGroup	= new TestCaseGroup(eglTestCtx, "recover_from_reset",		"Tests that attempt to create a new context after a context has occurred");
   2162 
   2163 		static const RobustnessTestCase::Params s_infiniteLoopCases[] =
   2164 		{
   2165 			RobustnessTestCase::Params("vertex",				"Provoke a context reset in vertex shader and ",				CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_VERT),
   2166 			RobustnessTestCase::Params("fragment",				"Provoke a context reset in fragment shader and ",				CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_FRAG),
   2167 			RobustnessTestCase::Params("vertex_and_fragment",	"Provoke a context reset in vertex and fragment shader and ",	CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_VERT_AND_FRAG),
   2168 			RobustnessTestCase::Params("compute",				"Provoke a context reset in compute shader and ",				CONTEXTRESETTYPE_INFINITE_LOOP,	SHADERTYPE_COMPUTE),
   2169 		};
   2170 
   2171 		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_infiniteLoopCases); ++testNdx)
   2172 		{
   2173 			const RobustnessTestCase::Params& test = s_infiniteLoopCases[testNdx];
   2174 			infiniteLoopResetTestGroup->addChild	(new BasicResetCase				(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2175 			infiniteLoopSyncTestGroup->addChild		(new SyncObjectResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + syncScenarioDescription).c_str(), test));
   2176 			infiniteLoopQueryTestGroup->addChild	(new QueryObjectResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + queryScenarioDescription).c_str(), test));
   2177 			infiniteLoopSharedTestGroup->addChild	(new SharedContextResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + sharedScenarioDescription).c_str(), test));
   2178 			infiniteLoopRecoverTestGroup->addChild	(new RecoverFromResetCase		(eglTestCtx, test.getName().c_str(), (test.getDescription() + recoverScenarioDescription).c_str(), test));
   2179 		}
   2180 
   2181 		infiniteLoopTestGroup->addChild(infiniteLoopResetTestGroup);
   2182 		infiniteLoopTestGroup->addChild(infiniteLoopSyncTestGroup);
   2183 		infiniteLoopTestGroup->addChild(infiniteLoopQueryTestGroup);
   2184 		infiniteLoopTestGroup->addChild(infiniteLoopSharedTestGroup);
   2185 		infiniteLoopTestGroup->addChild(infiniteLoopRecoverTestGroup);
   2186 	}
   2187 
   2188 	// out-of-bounds test cases
   2189 	{
   2190 		// robust context
   2191 		tcu::TestCaseGroup* const uboReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
   2192 		tcu::TestCaseGroup* const uboWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
   2193 		tcu::TestCaseGroup* const ssboWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
   2194 		tcu::TestCaseGroup* const ssboReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
   2195 		tcu::TestCaseGroup* const localWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
   2196 		tcu::TestCaseGroup* const localReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
   2197 
   2198 		// non-robust context (internal use only)
   2199 		tcu::TestCaseGroup* const uboReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
   2200 		tcu::TestCaseGroup* const uboWriteArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
   2201 		tcu::TestCaseGroup* const ssboWriteArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
   2202 		tcu::TestCaseGroup* const ssboReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
   2203 		tcu::TestCaseGroup* const localWriteArrayResetNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
   2204 		tcu::TestCaseGroup* const localReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
   2205 
   2206 		static const RobustnessTestCase::Params s_outOfBoundReadCases[] =
   2207 		{
   2208 			// ubo read only
   2209 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_READ),
   2210 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_READ),
   2211 			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),
   2212 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_UBO, READWRITETYPE_READ),
   2213 
   2214 			// ssbo read only
   2215 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
   2216 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
   2217 			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),
   2218 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
   2219 
   2220 			// local array read only
   2221 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
   2222 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
   2223 			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),
   2224 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
   2225 
   2226 			// ubo read only (non-robust)
   2227 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_READ),
   2228 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_READ),
   2229 			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),
   2230 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_UBO, READWRITETYPE_READ),
   2231 
   2232 			// ssbo read only (non-robust)
   2233 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
   2234 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
   2235 			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),
   2236 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_SSBO, READWRITETYPE_READ),
   2237 
   2238 			// local array read only (non-robust)
   2239 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
   2240 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
   2241 			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),
   2242 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
   2243 		};
   2244 
   2245 		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundReadCases); ++testNdx)
   2246 		{
   2247 			const RobustnessTestCase::Params& test = s_outOfBoundReadCases[testNdx];
   2248 
   2249 			if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
   2250 				uboReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2251 
   2252 			if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
   2253 				uboReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2254 
   2255 			if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
   2256 				ssboReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2257 
   2258 			if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
   2259 				ssboReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2260 
   2261 			if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
   2262 				localReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2263 
   2264 			if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
   2265 				localReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2266 		}
   2267 
   2268 		static const RobustnessTestCase::Params s_outOfBoundWriteCases[] =
   2269 		{
   2270 			// ubo write only
   2271 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
   2272 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
   2273 			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),
   2274 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
   2275 
   2276 			// ssbo write only
   2277 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
   2278 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
   2279 			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),
   2280 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
   2281 
   2282 			// local array write only
   2283 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
   2284 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
   2285 			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),
   2286 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
   2287 
   2288 			// ubo write only (non-robust)
   2289 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
   2290 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
   2291 			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),
   2292 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_UBO, READWRITETYPE_WRITE),
   2293 
   2294 			// ssbo write only (non-robust)
   2295 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
   2296 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
   2297 			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),
   2298 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
   2299 
   2300 			// local array write only (non-robust)
   2301 			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
   2302 			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
   2303 			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),
   2304 			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
   2305 		};
   2306 
   2307 		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundWriteCases); ++testNdx)
   2308 		{
   2309 			const RobustnessTestCase::Params& test = s_outOfBoundWriteCases[testNdx];
   2310 
   2311 				if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
   2312 					uboWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2313 
   2314 				if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
   2315 					uboWriteArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2316 
   2317 				if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
   2318 					ssboWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2319 
   2320 				if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
   2321 					ssboWriteArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2322 
   2323 				if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
   2324 					localWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2325 
   2326 				if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
   2327 					localWriteArrayResetNonRobustTestGroup->addChild	(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
   2328 		}
   2329 
   2330 		// robust Context
   2331 		tcu::TestCaseGroup* const outOfBoundsResetReadAccessTestGroup	= new TestCaseGroup(eglTestCtx, "reads",	"Out of bounds read accesses");
   2332 		tcu::TestCaseGroup* const outOfBoundsResetWriteAccessTestGroup	= new TestCaseGroup(eglTestCtx, "writes",	"Out of bounds write accesses");
   2333 
   2334 		outOfBoundsResetReadAccessTestGroup->addChild(uboReadArrayResetTestGroup);
   2335 		outOfBoundsResetReadAccessTestGroup->addChild(ssboReadArrayResetTestGroup);
   2336 		outOfBoundsResetReadAccessTestGroup->addChild(localReadArrayResetTestGroup);
   2337 
   2338 		outOfBoundsResetWriteAccessTestGroup->addChild(uboWriteArrayResetTestGroup);
   2339 		outOfBoundsResetWriteAccessTestGroup->addChild(ssboWriteArrayResetTestGroup);
   2340 		outOfBoundsResetWriteAccessTestGroup->addChild(localWriteArrayResetTestGroup);
   2341 
   2342 		tcu::TestCaseGroup* const outOfBoundsResetTestGroup		= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
   2343 
   2344 		outOfBoundsResetTestGroup->addChild(outOfBoundsResetReadAccessTestGroup);
   2345 		outOfBoundsResetTestGroup->addChild(outOfBoundsResetWriteAccessTestGroup);
   2346 
   2347 		outOfBoundsTestGroup->addChild(outOfBoundsResetTestGroup);
   2348 
   2349 		// non-robust Context (internal use only)
   2350 		tcu::TestCaseGroup* const outOfBoundsResetReadAccessNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "reads",	"Out of bounds read accesses");
   2351 		tcu::TestCaseGroup* const outOfBoundsResetWriteAccessNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "writes",	"Out of bounds write accesses");
   2352 
   2353 		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(uboReadArrayResetNonRobustTestGroup);
   2354 		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(ssboReadArrayResetNonRobustTestGroup);
   2355 		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(localReadArrayResetNonRobustTestGroup);
   2356 
   2357 		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(uboWriteArrayResetNonRobustTestGroup);
   2358 		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(ssboWriteArrayResetNonRobustTestGroup);
   2359 		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(localWriteArrayResetNonRobustTestGroup);
   2360 
   2361 		tcu::TestCaseGroup* const outOfBoundsResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
   2362 
   2363 		outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetReadAccessNonRobustTestGroup);
   2364 		outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetWriteAccessNonRobustTestGroup);
   2365 
   2366 		outOfBoundsNonRobustTestGroup->addChild(outOfBoundsResetNonRobustTestGroup);
   2367 	}
   2368 
   2369 	// fixed function test cases
   2370 	{
   2371 		// robust context
   2372 		tcu::TestCaseGroup* const fixedFunctionResetStatusTestGroup				= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
   2373 
   2374 		// non-robust context (internal use only)
   2375 		tcu::TestCaseGroup* const fixedFunctionResetStatusNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
   2376 
   2377 		static const RobustnessTestCase::Params s_fixedFunctionPipelineCases[] =
   2378 		{
   2379 			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),
   2380 			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),
   2381 
   2382 			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),
   2383 			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),
   2384 		};
   2385 
   2386 		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_fixedFunctionPipelineCases); ++testNdx)
   2387 		{
   2388 			const RobustnessTestCase::Params& test = s_fixedFunctionPipelineCases[testNdx];
   2389 			if (test.getRobustAccessType() == ROBUSTACCESS_TRUE)
   2390 				fixedFunctionResetStatusTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
   2391 			else
   2392 				fixedFunctionResetStatusNonRobustTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
   2393 		}
   2394 
   2395 		fixedFunctionTestGroup->addChild(fixedFunctionResetStatusTestGroup);
   2396 		fixedFunctionNonRobustTestGroup->addChild(fixedFunctionResetStatusNonRobustTestGroup);
   2397 	}
   2398 
   2399 	// context creation query cases
   2400 	{
   2401 		contextCreationTestGroup->addChild(new QueryRobustAccessCase	(eglTestCtx, "query_robust_access",		"Query robust access after successfully creating a robust context"));
   2402 		contextCreationTestGroup->addChild(new NoResetNotificationCase	(eglTestCtx, "no_reset_notification",	"Query reset notification strategy after specifying GL_NO_RESET_NOTIFICATION"));
   2403 		contextCreationTestGroup->addChild(new LoseContextOnResetCase	(eglTestCtx, "lose_context_on_reset",	"Query reset notification strategy after specifying GL_LOSE_CONTEXT_ON_RESET"));
   2404 	}
   2405 
   2406 	// invalid context creation cases
   2407 	{
   2408 		negativeContextTestGroup->addChild(new InvalidContextCase		(eglTestCtx, "invalid_robust_context_creation",			"Create a non-robust context but specify a reset notification strategy"));
   2409 		negativeContextTestGroup->addChild(new InvalidShareContextCase	(eglTestCtx, "invalid_robust_shared_context_creation",	"Create a context share group with conflicting reset notification strategies"));
   2410 	}
   2411 
   2412 	shadersTestGroup->addChild(infiniteLoopTestGroup);
   2413 	shadersTestGroup->addChild(outOfBoundsTestGroup);
   2414 	shadersTestGroup->addChild(outOfBoundsNonRobustTestGroup);
   2415 
   2416 	contextResetTestGroup->addChild(shadersTestGroup);
   2417 	contextResetTestGroup->addChild(fixedFunctionTestGroup);
   2418 	contextResetTestGroup->addChild(fixedFunctionNonRobustTestGroup);
   2419 
   2420 	group->addChild(contextCreationTestGroup);
   2421 	group->addChild(contextResetTestGroup);
   2422 	group->addChild(negativeContextTestGroup);
   2423 
   2424 	return group.release();
   2425 }
   2426 
   2427 } // egl
   2428 } // deqp
   2429