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