1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program EGL Module
3e5c31af7Sopenharmony_ci * ---------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2017 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Robustness tests for KHR_robustness.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "teglRobustnessTests.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
27e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ci#include "egluConfigFilter.hpp"
30e5c31af7Sopenharmony_ci#include "egluStrUtil.hpp"
31e5c31af7Sopenharmony_ci#include "egluUtil.hpp"
32e5c31af7Sopenharmony_ci#include "eglwLibrary.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp"
35e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
36e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp"
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
39e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp"
42e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
43e5c31af7Sopenharmony_ci#include "deThread.hpp"
44e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp"
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ci#include <set>
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_ciusing std::string;
49e5c31af7Sopenharmony_ciusing std::vector;
50e5c31af7Sopenharmony_ciusing std::set;
51e5c31af7Sopenharmony_ciusing tcu::TestLog;
52e5c31af7Sopenharmony_ci
53e5c31af7Sopenharmony_ciusing namespace eglw;
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_ciDE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY	== 0x8256);
56e5c31af7Sopenharmony_ciDE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET		== 0x8252);
57e5c31af7Sopenharmony_ciDE_STATIC_ASSERT(GL_NO_RESET_NOTIFICATION		== 0x8261);
58e5c31af7Sopenharmony_ci
59e5c31af7Sopenharmony_cinamespace deqp
60e5c31af7Sopenharmony_ci{
61e5c31af7Sopenharmony_cinamespace egl
62e5c31af7Sopenharmony_ci{
63e5c31af7Sopenharmony_cinamespace
64e5c31af7Sopenharmony_ci{
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_cienum ContextResetType
67e5c31af7Sopenharmony_ci{
68e5c31af7Sopenharmony_ci	CONTEXTRESETTYPE_SHADER_OOB,
69e5c31af7Sopenharmony_ci	CONTEXTRESETTYPE_FIXED_FUNC_OOB,
70e5c31af7Sopenharmony_ci};
71e5c31af7Sopenharmony_ci
72e5c31af7Sopenharmony_cienum ShaderType
73e5c31af7Sopenharmony_ci{
74e5c31af7Sopenharmony_ci	SHADERTYPE_VERT,
75e5c31af7Sopenharmony_ci	SHADERTYPE_FRAG,
76e5c31af7Sopenharmony_ci	SHADERTYPE_COMPUTE,
77e5c31af7Sopenharmony_ci	SHADERTYPE_VERT_AND_FRAG,
78e5c31af7Sopenharmony_ci};
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_cienum ReadWriteType
81e5c31af7Sopenharmony_ci{
82e5c31af7Sopenharmony_ci	READWRITETYPE_READ,
83e5c31af7Sopenharmony_ci	READWRITETYPE_WRITE,
84e5c31af7Sopenharmony_ci};
85e5c31af7Sopenharmony_ci
86e5c31af7Sopenharmony_cienum ResourceType
87e5c31af7Sopenharmony_ci{
88e5c31af7Sopenharmony_ci	RESOURCETYPE_UBO,
89e5c31af7Sopenharmony_ci	RESOURCETYPE_SSBO,
90e5c31af7Sopenharmony_ci	RESOURCETYPE_LOCAL_ARRAY,
91e5c31af7Sopenharmony_ci};
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_cienum FixedFunctionType
94e5c31af7Sopenharmony_ci{
95e5c31af7Sopenharmony_ci	FIXEDFUNCTIONTYPE_INDICES,
96e5c31af7Sopenharmony_ci	FIXEDFUNCTIONTYPE_VERTICES,
97e5c31af7Sopenharmony_ci};
98e5c31af7Sopenharmony_ci
99e5c31af7Sopenharmony_cienum RobustAccessType
100e5c31af7Sopenharmony_ci{
101e5c31af7Sopenharmony_ci	ROBUSTACCESS_TRUE,
102e5c31af7Sopenharmony_ci	ROBUSTACCESS_FALSE,
103e5c31af7Sopenharmony_ci};
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_civoid requireEGLExtension (const Library& egl, EGLDisplay eglDisplay, const char* requiredExtension)
106e5c31af7Sopenharmony_ci{
107e5c31af7Sopenharmony_ci	if (!eglu::hasExtension(egl, eglDisplay, requiredExtension))
108e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, (string(requiredExtension) + " not supported").c_str());
109e5c31af7Sopenharmony_ci}
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_cibool isWindow (const eglu::CandidateConfig& c)
112e5c31af7Sopenharmony_ci{
113e5c31af7Sopenharmony_ci	return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
114e5c31af7Sopenharmony_ci}
115e5c31af7Sopenharmony_ci
116e5c31af7Sopenharmony_citemplate <deUint32 Type>
117e5c31af7Sopenharmony_cibool renderable (const eglu::CandidateConfig& c)
118e5c31af7Sopenharmony_ci{
119e5c31af7Sopenharmony_ci	return (c.renderableType() & Type) == Type;
120e5c31af7Sopenharmony_ci}
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_cieglu::ConfigFilter getRenderableFilter (deUint32 bits)
123e5c31af7Sopenharmony_ci{
124e5c31af7Sopenharmony_ci	switch (bits)
125e5c31af7Sopenharmony_ci	{
126e5c31af7Sopenharmony_ci		case EGL_OPENGL_ES2_BIT:	return renderable<EGL_OPENGL_ES2_BIT>;
127e5c31af7Sopenharmony_ci		case EGL_OPENGL_ES3_BIT:	return renderable<EGL_OPENGL_ES3_BIT>;
128e5c31af7Sopenharmony_ci		case EGL_OPENGL_BIT:		return renderable<EGL_OPENGL_BIT>;
129e5c31af7Sopenharmony_ci		default:
130e5c31af7Sopenharmony_ci			DE_FATAL("Unknown EGL bitfied value");
131e5c31af7Sopenharmony_ci			return renderable<0>;
132e5c31af7Sopenharmony_ci	}
133e5c31af7Sopenharmony_ci}
134e5c31af7Sopenharmony_ci
135e5c31af7Sopenharmony_ciconst char* eglResetNotificationStrategyToString (EGLint strategy)
136e5c31af7Sopenharmony_ci{
137e5c31af7Sopenharmony_ci	switch (strategy)
138e5c31af7Sopenharmony_ci	{
139e5c31af7Sopenharmony_ci		case EGL_NO_RESET_NOTIFICATION_KHR:		return "EGL_NO_RESET_NOTIFICATION_KHR";
140e5c31af7Sopenharmony_ci		case EGL_LOSE_CONTEXT_ON_RESET_KHR:		return "EGL_LOSE_CONTEXT_ON_RESET_KHR";
141e5c31af7Sopenharmony_ci		default:
142e5c31af7Sopenharmony_ci			return "<Unknown>";
143e5c31af7Sopenharmony_ci	}
144e5c31af7Sopenharmony_ci}
145e5c31af7Sopenharmony_ci
146e5c31af7Sopenharmony_civoid logAttribList (const EglTestContext& eglTestCtx, const EGLint* attribList)
147e5c31af7Sopenharmony_ci{
148e5c31af7Sopenharmony_ci	const EGLint*		iter = &(attribList[0]);
149e5c31af7Sopenharmony_ci	std::ostringstream	attribListString;
150e5c31af7Sopenharmony_ci
151e5c31af7Sopenharmony_ci	while ((*iter) != EGL_NONE)
152e5c31af7Sopenharmony_ci	{
153e5c31af7Sopenharmony_ci		switch (*iter)
154e5c31af7Sopenharmony_ci		{
155e5c31af7Sopenharmony_ci		//	case EGL_CONTEXT_CLIENT_VERSION:
156e5c31af7Sopenharmony_ci			case EGL_CONTEXT_MAJOR_VERSION_KHR:
157e5c31af7Sopenharmony_ci				iter++;
158e5c31af7Sopenharmony_ci				attribListString << "EGL_CONTEXT_CLIENT_VERSION, " << (*iter) << ", ";
159e5c31af7Sopenharmony_ci				iter++;
160e5c31af7Sopenharmony_ci				break;
161e5c31af7Sopenharmony_ci
162e5c31af7Sopenharmony_ci			case EGL_CONTEXT_MINOR_VERSION_KHR:
163e5c31af7Sopenharmony_ci				iter++;
164e5c31af7Sopenharmony_ci				attribListString << "EGL_CONTEXT_MINOR_VERSION_KHR, " << (*iter) << ", ";
165e5c31af7Sopenharmony_ci				iter++;
166e5c31af7Sopenharmony_ci				break;
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_ci			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
169e5c31af7Sopenharmony_ci				iter++;
170e5c31af7Sopenharmony_ci				attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, "
171e5c31af7Sopenharmony_ci								 << eglResetNotificationStrategyToString(*iter) << ", ";
172e5c31af7Sopenharmony_ci				iter++;
173e5c31af7Sopenharmony_ci				break;
174e5c31af7Sopenharmony_ci
175e5c31af7Sopenharmony_ci			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
176e5c31af7Sopenharmony_ci				iter++;
177e5c31af7Sopenharmony_ci				attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, "
178e5c31af7Sopenharmony_ci								 << eglResetNotificationStrategyToString(*iter) << ", ";
179e5c31af7Sopenharmony_ci				iter++;
180e5c31af7Sopenharmony_ci				break;
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ci			case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
183e5c31af7Sopenharmony_ci				iter++;
184e5c31af7Sopenharmony_ci				attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, ";
185e5c31af7Sopenharmony_ci
186e5c31af7Sopenharmony_ci				if (*iter == EGL_FALSE || *iter == EGL_TRUE)
187e5c31af7Sopenharmony_ci					attribListString << (*iter ? "EGL_TRUE" : "EGL_FALSE") << ", ";
188e5c31af7Sopenharmony_ci				else
189e5c31af7Sopenharmony_ci					attribListString << (*iter) << ", ";
190e5c31af7Sopenharmony_ci				iter++;
191e5c31af7Sopenharmony_ci				break;
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ci			default:
194e5c31af7Sopenharmony_ci				DE_FATAL("Unsupported attribute");
195e5c31af7Sopenharmony_ci		}
196e5c31af7Sopenharmony_ci	}
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_ci	attribListString << "EGL_NONE";
199e5c31af7Sopenharmony_ci	eglTestCtx.getTestContext().getLog() << TestLog::Message
200e5c31af7Sopenharmony_ci										 << "EGL attrib list: { " << attribListString.str() << " }\n\n"
201e5c31af7Sopenharmony_ci										 << TestLog::EndMessage;
202e5c31af7Sopenharmony_ci}
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_ciclass RobustnessTestCase: public TestCase
205e5c31af7Sopenharmony_ci{
206e5c31af7Sopenharmony_cipublic:
207e5c31af7Sopenharmony_ci	class Params
208e5c31af7Sopenharmony_ci	{
209e5c31af7Sopenharmony_ci	public:
210e5c31af7Sopenharmony_ci							Params					(void) {}
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci							Params					(const string&				name,
213e5c31af7Sopenharmony_ci													 const string&				description,
214e5c31af7Sopenharmony_ci													 const RobustAccessType&	robustAccessType,
215e5c31af7Sopenharmony_ci													 const ContextResetType&	contextResetType,
216e5c31af7Sopenharmony_ci													 const FixedFunctionType&	fixedFunctionType);
217e5c31af7Sopenharmony_ci
218e5c31af7Sopenharmony_ci							Params					(const string&				name,
219e5c31af7Sopenharmony_ci													 const string&				description,
220e5c31af7Sopenharmony_ci													 const RobustAccessType&	robustAccessType,
221e5c31af7Sopenharmony_ci													 const ContextResetType&	contextResetType,
222e5c31af7Sopenharmony_ci													 const ShaderType&			shaderType,
223e5c31af7Sopenharmony_ci													 const ResourceType&		resourceType,
224e5c31af7Sopenharmony_ci													 const ReadWriteType&		readWriteType);
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci		const string&				getName					(void) const { return m_name;				}
227e5c31af7Sopenharmony_ci		const string&				getDescription			(void) const { return m_description;		}
228e5c31af7Sopenharmony_ci		const ContextResetType&		getContextResetType		(void) const { return m_contextResetType;	}
229e5c31af7Sopenharmony_ci		const ShaderType&			getShaderType			(void) const { return m_shaderType;			}
230e5c31af7Sopenharmony_ci		const ResourceType&			getResourceType			(void) const { return m_resourceType;		}
231e5c31af7Sopenharmony_ci		const ReadWriteType&		getReadWriteType		(void) const { return m_readWriteType;		}
232e5c31af7Sopenharmony_ci		const FixedFunctionType&	getFixedFunctionType	(void) const { return m_fixedFunctionType;	}
233e5c31af7Sopenharmony_ci		const RobustAccessType&		getRobustAccessType		(void) const { return m_robustAccessType;	}
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_ci	private:
236e5c31af7Sopenharmony_ci		string				m_name;
237e5c31af7Sopenharmony_ci		string				m_description;
238e5c31af7Sopenharmony_ci		RobustAccessType	m_robustAccessType;
239e5c31af7Sopenharmony_ci		ContextResetType	m_contextResetType;
240e5c31af7Sopenharmony_ci		ShaderType			m_shaderType;
241e5c31af7Sopenharmony_ci		ResourceType		m_resourceType;
242e5c31af7Sopenharmony_ci		ReadWriteType		m_readWriteType;
243e5c31af7Sopenharmony_ci		FixedFunctionType	m_fixedFunctionType;
244e5c31af7Sopenharmony_ci	};
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci			RobustnessTestCase			(EglTestContext& eglTestCtx, const char* name, const char* description);
247e5c31af7Sopenharmony_ci			RobustnessTestCase			(EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
248e5c31af7Sopenharmony_ci			~RobustnessTestCase			(void);
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci	void	checkRequiredEGLExtensions	(const EGLint* attribList);
251e5c31af7Sopenharmony_ci
252e5c31af7Sopenharmony_ciprotected:
253e5c31af7Sopenharmony_ci	Params					m_params;
254e5c31af7Sopenharmony_ci	EGLDisplay				m_eglDisplay;
255e5c31af7Sopenharmony_ci	EGLConfig				m_eglConfig;
256e5c31af7Sopenharmony_ci	EGLSurface				m_eglSurface;
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ciprivate:
259e5c31af7Sopenharmony_ci	void					init					(void);
260e5c31af7Sopenharmony_ci	void					deinit					(void);
261e5c31af7Sopenharmony_ci	void					initEGLSurface			(void);
262e5c31af7Sopenharmony_ci	EGLConfig				getEGLConfig			(void);
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_ci	eglu::NativeWindow*		m_window;
265e5c31af7Sopenharmony_ci};
266e5c31af7Sopenharmony_ci
267e5c31af7Sopenharmony_ciRobustnessTestCase::Params::Params (const string&				name,
268e5c31af7Sopenharmony_ci									const string&				description,
269e5c31af7Sopenharmony_ci									const RobustAccessType&		robustAccessType,
270e5c31af7Sopenharmony_ci									const ContextResetType&		contextResetType,
271e5c31af7Sopenharmony_ci									const FixedFunctionType&	fixedFunctionType)
272e5c31af7Sopenharmony_ci	: m_name				(name)
273e5c31af7Sopenharmony_ci	, m_description			(description)
274e5c31af7Sopenharmony_ci	, m_robustAccessType	(robustAccessType)
275e5c31af7Sopenharmony_ci	, m_contextResetType	(contextResetType)
276e5c31af7Sopenharmony_ci	, m_fixedFunctionType	(fixedFunctionType)
277e5c31af7Sopenharmony_ci{
278e5c31af7Sopenharmony_ci}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ciRobustnessTestCase::Params::Params (const string&				name,
281e5c31af7Sopenharmony_ci									const string&				description,
282e5c31af7Sopenharmony_ci									const RobustAccessType&		robustAccessType,
283e5c31af7Sopenharmony_ci									const ContextResetType&		contextResetType,
284e5c31af7Sopenharmony_ci									const ShaderType&			shaderType,
285e5c31af7Sopenharmony_ci									const ResourceType&			resourceType,
286e5c31af7Sopenharmony_ci									const ReadWriteType&		readWriteType)
287e5c31af7Sopenharmony_ci	: m_name				(name)
288e5c31af7Sopenharmony_ci	, m_description			(description)
289e5c31af7Sopenharmony_ci	, m_robustAccessType	(robustAccessType)
290e5c31af7Sopenharmony_ci	, m_contextResetType	(contextResetType)
291e5c31af7Sopenharmony_ci	, m_shaderType			(shaderType)
292e5c31af7Sopenharmony_ci	, m_resourceType		(resourceType)
293e5c31af7Sopenharmony_ci	, m_readWriteType		(readWriteType)
294e5c31af7Sopenharmony_ci{
295e5c31af7Sopenharmony_ci}
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ciRobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description)
298e5c31af7Sopenharmony_ci	: TestCase			(eglTestCtx, name, description)
299e5c31af7Sopenharmony_ci	, m_eglDisplay		(EGL_NO_DISPLAY)
300e5c31af7Sopenharmony_ci	, m_eglConfig		(0)
301e5c31af7Sopenharmony_ci	, m_eglSurface		(EGL_NO_SURFACE)
302e5c31af7Sopenharmony_ci	, m_window			(DE_NULL)
303e5c31af7Sopenharmony_ci{
304e5c31af7Sopenharmony_ci}
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ciRobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
307e5c31af7Sopenharmony_ci	: TestCase			(eglTestCtx, name, description)
308e5c31af7Sopenharmony_ci	, m_params			(params)
309e5c31af7Sopenharmony_ci	, m_eglDisplay		(EGL_NO_DISPLAY)
310e5c31af7Sopenharmony_ci	, m_eglConfig		(0)
311e5c31af7Sopenharmony_ci	, m_eglSurface		(EGL_NO_SURFACE)
312e5c31af7Sopenharmony_ci	, m_window			(DE_NULL)
313e5c31af7Sopenharmony_ci{
314e5c31af7Sopenharmony_ci}
315e5c31af7Sopenharmony_ci
316e5c31af7Sopenharmony_ciRobustnessTestCase::~RobustnessTestCase (void)
317e5c31af7Sopenharmony_ci{
318e5c31af7Sopenharmony_ci	deinit();
319e5c31af7Sopenharmony_ci}
320e5c31af7Sopenharmony_ci
321e5c31af7Sopenharmony_civoid RobustnessTestCase::init (void)
322e5c31af7Sopenharmony_ci{
323e5c31af7Sopenharmony_ci	m_eglDisplay	= eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
324e5c31af7Sopenharmony_ci	m_eglConfig		= getEGLConfig();
325e5c31af7Sopenharmony_ci
326e5c31af7Sopenharmony_ci	initEGLSurface();
327e5c31af7Sopenharmony_ci}
328e5c31af7Sopenharmony_ci
329e5c31af7Sopenharmony_civoid RobustnessTestCase::deinit (void)
330e5c31af7Sopenharmony_ci{
331e5c31af7Sopenharmony_ci	const Library& egl = m_eglTestCtx.getLibrary();
332e5c31af7Sopenharmony_ci
333e5c31af7Sopenharmony_ci	if (m_eglSurface != EGL_NO_SURFACE)
334e5c31af7Sopenharmony_ci	{
335e5c31af7Sopenharmony_ci		egl.destroySurface(m_eglDisplay, m_eglSurface);
336e5c31af7Sopenharmony_ci		m_eglSurface = EGL_NO_SURFACE;
337e5c31af7Sopenharmony_ci	}
338e5c31af7Sopenharmony_ci	if (m_eglDisplay != EGL_NO_DISPLAY)
339e5c31af7Sopenharmony_ci	{
340e5c31af7Sopenharmony_ci		egl.terminate(m_eglDisplay);
341e5c31af7Sopenharmony_ci		m_eglDisplay = EGL_NO_DISPLAY;
342e5c31af7Sopenharmony_ci	}
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci	delete m_window;
345e5c31af7Sopenharmony_ci	m_window = DE_NULL;
346e5c31af7Sopenharmony_ci}
347e5c31af7Sopenharmony_ci
348e5c31af7Sopenharmony_ciEGLConfig RobustnessTestCase::getEGLConfig (void)
349e5c31af7Sopenharmony_ci{
350e5c31af7Sopenharmony_ci	eglu::FilterList filters;
351e5c31af7Sopenharmony_ci	filters << isWindow << getRenderableFilter(EGL_OPENGL_ES3_BIT);
352e5c31af7Sopenharmony_ci	return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, filters);
353e5c31af7Sopenharmony_ci}
354e5c31af7Sopenharmony_ci
355e5c31af7Sopenharmony_civoid RobustnessTestCase::initEGLSurface (void)
356e5c31af7Sopenharmony_ci{
357e5c31af7Sopenharmony_ci	EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), bindAPI(EGL_OPENGL_ES_API));
358e5c31af7Sopenharmony_ci
359e5c31af7Sopenharmony_ci	const eglu::NativeWindowFactory& factory =	eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
360e5c31af7Sopenharmony_ci
361e5c31af7Sopenharmony_ci	const eglu::WindowParams	windowParams	=	eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine()));
362e5c31af7Sopenharmony_ci	m_window									=	factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL, windowParams);
363e5c31af7Sopenharmony_ci	m_eglSurface								=	eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
364e5c31af7Sopenharmony_ci}
365e5c31af7Sopenharmony_ci
366e5c31af7Sopenharmony_ciglu::ApiType paramsToApiType (const RobustnessTestCase::Params& params)
367e5c31af7Sopenharmony_ci{
368e5c31af7Sopenharmony_ci	EGLint				minorVersion	= 0;
369e5c31af7Sopenharmony_ci	if (params.getShaderType()		 == SHADERTYPE_COMPUTE	||
370e5c31af7Sopenharmony_ci		params.getResourceType()	 == RESOURCETYPE_SSBO	||
371e5c31af7Sopenharmony_ci		params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
372e5c31af7Sopenharmony_ci	{
373e5c31af7Sopenharmony_ci		minorVersion = 1;
374e5c31af7Sopenharmony_ci	}
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ci	return glu::ApiType::es(3, minorVersion);
377e5c31af7Sopenharmony_ci}
378e5c31af7Sopenharmony_ci
379e5c31af7Sopenharmony_civoid RobustnessTestCase::checkRequiredEGLExtensions (const EGLint* attribList)
380e5c31af7Sopenharmony_ci{
381e5c31af7Sopenharmony_ci	set<string>		requiredExtensions;
382e5c31af7Sopenharmony_ci	vector<string>	extensions			= eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_eglDisplay);
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci	{
385e5c31af7Sopenharmony_ci		const EGLint* iter = attribList;
386e5c31af7Sopenharmony_ci
387e5c31af7Sopenharmony_ci		while ((*iter) != EGL_NONE)
388e5c31af7Sopenharmony_ci		{
389e5c31af7Sopenharmony_ci			switch (*iter)
390e5c31af7Sopenharmony_ci			{
391e5c31af7Sopenharmony_ci				case EGL_CONTEXT_MAJOR_VERSION_KHR: iter++;
392e5c31af7Sopenharmony_ci					iter++;
393e5c31af7Sopenharmony_ci					break;
394e5c31af7Sopenharmony_ci
395e5c31af7Sopenharmony_ci				case EGL_CONTEXT_MINOR_VERSION_KHR:
396e5c31af7Sopenharmony_ci					iter++;
397e5c31af7Sopenharmony_ci					requiredExtensions.insert("EGL_KHR_create_context");
398e5c31af7Sopenharmony_ci					iter++;
399e5c31af7Sopenharmony_ci					break;
400e5c31af7Sopenharmony_ci
401e5c31af7Sopenharmony_ci				case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
402e5c31af7Sopenharmony_ci				case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
403e5c31af7Sopenharmony_ci					iter++;
404e5c31af7Sopenharmony_ci					requiredExtensions.insert("EGL_EXT_create_context_robustness");
405e5c31af7Sopenharmony_ci					iter++;
406e5c31af7Sopenharmony_ci					break;
407e5c31af7Sopenharmony_ci
408e5c31af7Sopenharmony_ci				default:
409e5c31af7Sopenharmony_ci					DE_ASSERT(DE_FALSE);
410e5c31af7Sopenharmony_ci			}
411e5c31af7Sopenharmony_ci		}
412e5c31af7Sopenharmony_ci	}
413e5c31af7Sopenharmony_ci
414e5c31af7Sopenharmony_ci	for (std::set<string>::const_iterator reqExt = requiredExtensions.begin(); reqExt != requiredExtensions.end(); ++reqExt)
415e5c31af7Sopenharmony_ci	{
416e5c31af7Sopenharmony_ci		if (!de::contains(extensions.begin(), extensions.end(), *reqExt))
417e5c31af7Sopenharmony_ci		{
418e5c31af7Sopenharmony_ci			const char* const extension = reqExt->c_str();
419e5c31af7Sopenharmony_ci			requireEGLExtension(m_eglTestCtx.getLibrary(), m_eglDisplay, extension);
420e5c31af7Sopenharmony_ci		}
421e5c31af7Sopenharmony_ci	}
422e5c31af7Sopenharmony_ci}
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_civoid checkRequiredGLSupport (const glw::Functions& gl, glu::ApiType requiredApi)
425e5c31af7Sopenharmony_ci{
426e5c31af7Sopenharmony_ci	if (!glu::hasExtension(gl, requiredApi, "GL_KHR_robustness") && !glu::hasExtension(gl, requiredApi, "GL_EXT_robustness"))
427e5c31af7Sopenharmony_ci	{
428e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, (string("GL_KHR_robustness and GL_EXT_robustness") + " not supported").c_str());
429e5c31af7Sopenharmony_ci	}
430e5c31af7Sopenharmony_ci	else
431e5c31af7Sopenharmony_ci	{
432e5c31af7Sopenharmony_ci		int realMinorVersion = 0;
433e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_MINOR_VERSION, &realMinorVersion);
434e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Get minor version failed");
435e5c31af7Sopenharmony_ci
436e5c31af7Sopenharmony_ci		if (realMinorVersion < requiredApi.getMinorVersion())
437e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Test case requires GLES 3.1");
438e5c31af7Sopenharmony_ci	}
439e5c31af7Sopenharmony_ci}
440e5c31af7Sopenharmony_ci
441e5c31af7Sopenharmony_civoid checkGLSupportForParams (const glw::Functions& gl, const RobustnessTestCase::Params& params)
442e5c31af7Sopenharmony_ci{
443e5c31af7Sopenharmony_ci	int minorVersion = 0;
444e5c31af7Sopenharmony_ci	if (params.getShaderType()		  == SHADERTYPE_COMPUTE	||
445e5c31af7Sopenharmony_ci		params.getResourceType()	  == RESOURCETYPE_SSBO	||
446e5c31af7Sopenharmony_ci		params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
447e5c31af7Sopenharmony_ci	{
448e5c31af7Sopenharmony_ci		minorVersion = 1;
449e5c31af7Sopenharmony_ci	}
450e5c31af7Sopenharmony_ci	checkRequiredGLSupport(gl, glu::ApiType::es(3, minorVersion));
451e5c31af7Sopenharmony_ci}
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_ciclass RenderingContext
454e5c31af7Sopenharmony_ci{
455e5c31af7Sopenharmony_cipublic:
456e5c31af7Sopenharmony_ci							RenderingContext					(const EglTestContext&	eglTestCtx,
457e5c31af7Sopenharmony_ci																 const EGLint*			attribList,
458e5c31af7Sopenharmony_ci																 const EGLConfig&		config,
459e5c31af7Sopenharmony_ci																 const EGLDisplay&		display,
460e5c31af7Sopenharmony_ci																 const EGLContext&		sharedContext);
461e5c31af7Sopenharmony_ci							~RenderingContext					(void);
462e5c31af7Sopenharmony_ci
463e5c31af7Sopenharmony_ci	void					initGLFunctions						(glw::Functions* gl, const glu::ApiType apiType);
464e5c31af7Sopenharmony_ci	void					makeCurrent							(const EGLSurface& surface);
465e5c31af7Sopenharmony_ci	EGLContext				getContext							(void);
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_ciprivate:
468e5c31af7Sopenharmony_ci	const EglTestContext&	m_eglTestCtx;
469e5c31af7Sopenharmony_ci	const EGLint*			m_attribList;
470e5c31af7Sopenharmony_ci	const EGLConfig&		m_config;
471e5c31af7Sopenharmony_ci	const EGLDisplay&		m_display;
472e5c31af7Sopenharmony_ci	const Library&			m_egl;
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci	EGLContext				m_context;
475e5c31af7Sopenharmony_ci
476e5c31af7Sopenharmony_ci	void					createContext						(const EGLConfig& sharedConfig);
477e5c31af7Sopenharmony_ci	void					destroyContext						(void);
478e5c31af7Sopenharmony_ci
479e5c31af7Sopenharmony_ci							RenderingContext					(const RenderingContext&);
480e5c31af7Sopenharmony_ci	RenderingContext&		operator=							(const RenderingContext&);
481e5c31af7Sopenharmony_ci};
482e5c31af7Sopenharmony_ci
483e5c31af7Sopenharmony_ciRenderingContext::RenderingContext (const EglTestContext&	 eglTestCtx,
484e5c31af7Sopenharmony_ci									const EGLint*			 attribList,
485e5c31af7Sopenharmony_ci									const EGLConfig&		 config,
486e5c31af7Sopenharmony_ci									const EGLDisplay&		 display,
487e5c31af7Sopenharmony_ci									const EGLContext&		 sharedContext)
488e5c31af7Sopenharmony_ci	: m_eglTestCtx		(eglTestCtx)
489e5c31af7Sopenharmony_ci	, m_attribList		(attribList)
490e5c31af7Sopenharmony_ci	, m_config			(config)
491e5c31af7Sopenharmony_ci	, m_display			(display)
492e5c31af7Sopenharmony_ci	, m_egl				(eglTestCtx.getLibrary())
493e5c31af7Sopenharmony_ci	, m_context			(EGL_NO_CONTEXT)
494e5c31af7Sopenharmony_ci{
495e5c31af7Sopenharmony_ci	logAttribList(eglTestCtx, m_attribList);
496e5c31af7Sopenharmony_ci	createContext(sharedContext);
497e5c31af7Sopenharmony_ci}
498e5c31af7Sopenharmony_ci
499e5c31af7Sopenharmony_ciRenderingContext::~RenderingContext (void)
500e5c31af7Sopenharmony_ci{
501e5c31af7Sopenharmony_ci	destroyContext();
502e5c31af7Sopenharmony_ci}
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_civoid RenderingContext::createContext (const EGLConfig& sharedContext)
505e5c31af7Sopenharmony_ci{
506e5c31af7Sopenharmony_ci	m_context = m_egl.createContext(m_display, m_config, sharedContext, m_attribList);
507e5c31af7Sopenharmony_ci	EGLU_CHECK_MSG(m_egl, "eglCreateContext()");
508e5c31af7Sopenharmony_ci}
509e5c31af7Sopenharmony_ci
510e5c31af7Sopenharmony_civoid RenderingContext::destroyContext (void)
511e5c31af7Sopenharmony_ci{
512e5c31af7Sopenharmony_ci	EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
513e5c31af7Sopenharmony_ci
514e5c31af7Sopenharmony_ci	if (m_context != EGL_NO_CONTEXT)
515e5c31af7Sopenharmony_ci		m_egl.destroyContext(m_display, m_context);
516e5c31af7Sopenharmony_ci}
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_civoid RenderingContext::makeCurrent (const EGLSurface& surface)
519e5c31af7Sopenharmony_ci{
520e5c31af7Sopenharmony_ci	EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, surface, surface, m_context));
521e5c31af7Sopenharmony_ci}
522e5c31af7Sopenharmony_ci
523e5c31af7Sopenharmony_civoid RenderingContext::initGLFunctions (glw::Functions *gl, const glu::ApiType apiType)
524e5c31af7Sopenharmony_ci{
525e5c31af7Sopenharmony_ci	// \todo [2017-03-23 pyry] Current version has 2 somewhat ugly hacks:
526e5c31af7Sopenharmony_ci	//
527e5c31af7Sopenharmony_ci	// 1) Core functions are loaded twice. We need glGetString(i) to query supported
528e5c31af7Sopenharmony_ci	//    extensions to determine if we need to load EXT or KHR-suffixed robustness
529e5c31af7Sopenharmony_ci	//    functions. This could be fixed by exposing glw::FunctionLoader in EglTestContext
530e5c31af7Sopenharmony_ci	//    for example.
531e5c31af7Sopenharmony_ci	//
532e5c31af7Sopenharmony_ci	// 2) We assume that calling code will check for KHR_robustness or EXT_robustness
533e5c31af7Sopenharmony_ci	//    support after calling initGLFunctions(). We could move the check here.
534e5c31af7Sopenharmony_ci
535e5c31af7Sopenharmony_ci	m_eglTestCtx.initGLFunctions(gl, apiType);
536e5c31af7Sopenharmony_ci
537e5c31af7Sopenharmony_ci	{
538e5c31af7Sopenharmony_ci		const char* const	robustnessExt	= glu::hasExtension(*gl, apiType, "GL_KHR_robustness") ? "GL_KHR_robustness" : "GL_EXT_robustness";
539e5c31af7Sopenharmony_ci		const char* const	extensions[]	= { robustnessExt };
540e5c31af7Sopenharmony_ci
541e5c31af7Sopenharmony_ci		m_eglTestCtx.initGLFunctions(gl, apiType, DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
542e5c31af7Sopenharmony_ci	}
543e5c31af7Sopenharmony_ci}
544e5c31af7Sopenharmony_ci
545e5c31af7Sopenharmony_ciEGLContext RenderingContext::getContext (void)
546e5c31af7Sopenharmony_ci{
547e5c31af7Sopenharmony_ci	return m_context;
548e5c31af7Sopenharmony_ci}
549e5c31af7Sopenharmony_ci
550e5c31af7Sopenharmony_ciclass ContextReset
551e5c31af7Sopenharmony_ci{
552e5c31af7Sopenharmony_cipublic:
553e5c31af7Sopenharmony_ci						ContextReset				(glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
554e5c31af7Sopenharmony_ci						ContextReset				(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);
555e5c31af7Sopenharmony_ci
556e5c31af7Sopenharmony_ci	virtual				~ContextReset				(void) {}
557e5c31af7Sopenharmony_ci
558e5c31af7Sopenharmony_ci	virtual void		setup						(void) = 0;
559e5c31af7Sopenharmony_ci	virtual void		draw						(void) = 0;
560e5c31af7Sopenharmony_ci	virtual void		teardown					(void) = 0;
561e5c31af7Sopenharmony_ci
562e5c31af7Sopenharmony_ci	void				finish						(void);
563e5c31af7Sopenharmony_ci
564e5c31af7Sopenharmony_ci	glw::GLint			getError					(void);
565e5c31af7Sopenharmony_ci	glw::GLint			getGraphicsResetStatus		(void);
566e5c31af7Sopenharmony_ci
567e5c31af7Sopenharmony_ci	glw::GLsync			getSyncObject				(void) const { return m_sync; }
568e5c31af7Sopenharmony_ci	glw::GLuint			getQueryID					(void) const { return m_queryID; }
569e5c31af7Sopenharmony_ci
570e5c31af7Sopenharmony_ci	glw::Functions&		m_gl;
571e5c31af7Sopenharmony_ci	tcu::TestLog&		m_log;
572e5c31af7Sopenharmony_ci	ShaderType			m_shaderType;
573e5c31af7Sopenharmony_ci	ResourceType		m_resourceType;
574e5c31af7Sopenharmony_ci	ReadWriteType		m_readWriteType;
575e5c31af7Sopenharmony_ci	FixedFunctionType	m_fixedFunctionType;
576e5c31af7Sopenharmony_ci
577e5c31af7Sopenharmony_ciprivate:
578e5c31af7Sopenharmony_ci						ContextReset				(const ContextReset&);
579e5c31af7Sopenharmony_ci	ContextReset&		operator=					(const ContextReset&);
580e5c31af7Sopenharmony_ci
581e5c31af7Sopenharmony_ci	glw::GLuint			m_queryID;
582e5c31af7Sopenharmony_ci	glw::GLsync			m_sync;
583e5c31af7Sopenharmony_ci};
584e5c31af7Sopenharmony_ci
585e5c31af7Sopenharmony_ciContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
586e5c31af7Sopenharmony_ci	: m_gl					(gl)
587e5c31af7Sopenharmony_ci	, m_log					(log)
588e5c31af7Sopenharmony_ci	, m_fixedFunctionType	(fixedFunctionType)
589e5c31af7Sopenharmony_ci{
590e5c31af7Sopenharmony_ci}
591e5c31af7Sopenharmony_ci
592e5c31af7Sopenharmony_ciContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
593e5c31af7Sopenharmony_ci	: m_gl				(gl)
594e5c31af7Sopenharmony_ci	, m_log				(log)
595e5c31af7Sopenharmony_ci	, m_shaderType		(shaderType)
596e5c31af7Sopenharmony_ci	, m_resourceType	(resourceType)
597e5c31af7Sopenharmony_ci	, m_readWriteType	(readWriteType)
598e5c31af7Sopenharmony_ci{
599e5c31af7Sopenharmony_ci}
600e5c31af7Sopenharmony_ci
601e5c31af7Sopenharmony_civoid ContextReset::finish (void)
602e5c31af7Sopenharmony_ci{
603e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, finish());
604e5c31af7Sopenharmony_ci}
605e5c31af7Sopenharmony_ci
606e5c31af7Sopenharmony_ciglw::GLint ContextReset::getError (void)
607e5c31af7Sopenharmony_ci{
608e5c31af7Sopenharmony_ci	glw::GLint error;
609e5c31af7Sopenharmony_ci	error = m_gl.getError();
610e5c31af7Sopenharmony_ci
611e5c31af7Sopenharmony_ci	return error;
612e5c31af7Sopenharmony_ci}
613e5c31af7Sopenharmony_ci
614e5c31af7Sopenharmony_ciglw::GLint ContextReset::getGraphicsResetStatus (void)
615e5c31af7Sopenharmony_ci{
616e5c31af7Sopenharmony_ci	glw::GLint resetStatus;
617e5c31af7Sopenharmony_ci	resetStatus = m_gl.getGraphicsResetStatus();
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci	return resetStatus;
620e5c31af7Sopenharmony_ci}
621e5c31af7Sopenharmony_ci
622e5c31af7Sopenharmony_ciclass FixedFunctionOOB : public ContextReset
623e5c31af7Sopenharmony_ci{
624e5c31af7Sopenharmony_cipublic:
625e5c31af7Sopenharmony_ci							FixedFunctionOOB			(glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
626e5c31af7Sopenharmony_ci							~FixedFunctionOOB			(void);
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci	struct TestConfig
629e5c31af7Sopenharmony_ci	{
630e5c31af7Sopenharmony_ci		int textureWidth;
631e5c31af7Sopenharmony_ci		int textureHeight;
632e5c31af7Sopenharmony_ci	};
633e5c31af7Sopenharmony_ci
634e5c31af7Sopenharmony_ci	virtual void			setup						(void);
635e5c31af7Sopenharmony_ci	virtual void			draw						(void);
636e5c31af7Sopenharmony_ci	virtual void			teardown					(void);
637e5c31af7Sopenharmony_ci
638e5c31af7Sopenharmony_ciprivate:
639e5c31af7Sopenharmony_ci	glu::ProgramSources		genSources					(void);
640e5c31af7Sopenharmony_ci	glw::GLuint				m_coordinatesBuffer;
641e5c31af7Sopenharmony_ci	glw::GLint				m_coordLocation;
642e5c31af7Sopenharmony_ci};
643e5c31af7Sopenharmony_ci
644e5c31af7Sopenharmony_ciFixedFunctionOOB::FixedFunctionOOB (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
645e5c31af7Sopenharmony_ci	: ContextReset(gl, log, fixedFunctionType)
646e5c31af7Sopenharmony_ci	, m_coordinatesBuffer	(0)
647e5c31af7Sopenharmony_ci	, m_coordLocation		(0)
648e5c31af7Sopenharmony_ci{
649e5c31af7Sopenharmony_ci}
650e5c31af7Sopenharmony_ci
651e5c31af7Sopenharmony_ciFixedFunctionOOB::~FixedFunctionOOB (void)
652e5c31af7Sopenharmony_ci{
653e5c31af7Sopenharmony_ci	try
654e5c31af7Sopenharmony_ci	{
655e5c31af7Sopenharmony_ci		// Reset GL_CONTEXT_LOST error before destroying resources
656e5c31af7Sopenharmony_ci		m_gl.getGraphicsResetStatus();
657e5c31af7Sopenharmony_ci		teardown();
658e5c31af7Sopenharmony_ci	}
659e5c31af7Sopenharmony_ci	catch (...)
660e5c31af7Sopenharmony_ci	{
661e5c31af7Sopenharmony_ci		// Ignore GL errors from teardown()
662e5c31af7Sopenharmony_ci	}
663e5c31af7Sopenharmony_ci}
664e5c31af7Sopenharmony_ci
665e5c31af7Sopenharmony_ciglu::ProgramSources FixedFunctionOOB::genSources (void)
666e5c31af7Sopenharmony_ci{
667e5c31af7Sopenharmony_ci	const char* const vert =
668e5c31af7Sopenharmony_ci		"#version 300 es\n"
669e5c31af7Sopenharmony_ci		"in highp vec4 a_position;\n"
670e5c31af7Sopenharmony_ci		"void main (void)\n"
671e5c31af7Sopenharmony_ci		"{\n"
672e5c31af7Sopenharmony_ci		"	gl_Position = a_position;\n"
673e5c31af7Sopenharmony_ci		"}\n";
674e5c31af7Sopenharmony_ci
675e5c31af7Sopenharmony_ci	const char* const frag =
676e5c31af7Sopenharmony_ci		"#version 300 es\n"
677e5c31af7Sopenharmony_ci		"layout(location = 0) out highp vec4 fragColor;\n"
678e5c31af7Sopenharmony_ci		"void main (void)\n"
679e5c31af7Sopenharmony_ci		"{\n"
680e5c31af7Sopenharmony_ci		"	fragColor = vec4(1.0f);\n"
681e5c31af7Sopenharmony_ci		"}\n";
682e5c31af7Sopenharmony_ci
683e5c31af7Sopenharmony_ci	return glu::ProgramSources() << glu::VertexSource(vert) << glu::FragmentSource(frag);
684e5c31af7Sopenharmony_ci}
685e5c31af7Sopenharmony_ci
686e5c31af7Sopenharmony_civoid FixedFunctionOOB::setup (void)
687e5c31af7Sopenharmony_ci{
688e5c31af7Sopenharmony_ci	glu::ShaderProgram program(m_gl, genSources());
689e5c31af7Sopenharmony_ci
690e5c31af7Sopenharmony_ci	m_log << program;
691e5c31af7Sopenharmony_ci
692e5c31af7Sopenharmony_ci	if (!program.isOk())
693e5c31af7Sopenharmony_ci		TCU_FAIL("Failed to compile shader program");
694e5c31af7Sopenharmony_ci
695e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
696e5c31af7Sopenharmony_ci
697e5c31af7Sopenharmony_ci	const glw::GLfloat coords[] =
698e5c31af7Sopenharmony_ci	{
699e5c31af7Sopenharmony_ci		-1.0f, -1.0f,
700e5c31af7Sopenharmony_ci		 1.0f, -1.0f,
701e5c31af7Sopenharmony_ci		 1.0f,	1.0f,
702e5c31af7Sopenharmony_ci		-1.0f,	1.0f
703e5c31af7Sopenharmony_ci	};
704e5c31af7Sopenharmony_ci
705e5c31af7Sopenharmony_ci	m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
706e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
707e5c31af7Sopenharmony_ci	TCU_CHECK(m_coordLocation != (glw::GLint)-1);
708e5c31af7Sopenharmony_ci
709e5c31af7Sopenharmony_ci	// Load the vertex data
710e5c31af7Sopenharmony_ci	m_coordinatesBuffer = 0;
711e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
712e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
713e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
714e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
715e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
716e5c31af7Sopenharmony_ci}
717e5c31af7Sopenharmony_ci
718e5c31af7Sopenharmony_civoid FixedFunctionOOB::draw (void)
719e5c31af7Sopenharmony_ci{
720e5c31af7Sopenharmony_ci	const glw::GLint bad_indices[] = {0, 10, 100, 1000, 10000, 100000};
721e5c31af7Sopenharmony_ci
722e5c31af7Sopenharmony_ci	if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_INDICES)
723e5c31af7Sopenharmony_ci		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, bad_indices);
724e5c31af7Sopenharmony_ci	else if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_VERTICES)
725e5c31af7Sopenharmony_ci		m_gl.drawArrays(GL_TRIANGLES, 0, 1000);
726e5c31af7Sopenharmony_ci	else
727e5c31af7Sopenharmony_ci		DE_FATAL("Unknown fixed function type");
728e5c31af7Sopenharmony_ci}
729e5c31af7Sopenharmony_ci
730e5c31af7Sopenharmony_civoid FixedFunctionOOB::teardown (void)
731e5c31af7Sopenharmony_ci{
732e5c31af7Sopenharmony_ci	if (m_coordLocation)
733e5c31af7Sopenharmony_ci	{
734e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
735e5c31af7Sopenharmony_ci		m_coordLocation = 0;
736e5c31af7Sopenharmony_ci	}
737e5c31af7Sopenharmony_ci
738e5c31af7Sopenharmony_ci	if (m_coordinatesBuffer)
739e5c31af7Sopenharmony_ci	{
740e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
741e5c31af7Sopenharmony_ci		m_coordinatesBuffer = 0;
742e5c31af7Sopenharmony_ci	}
743e5c31af7Sopenharmony_ci
744e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
745e5c31af7Sopenharmony_ci}
746e5c31af7Sopenharmony_ci
747e5c31af7Sopenharmony_ciclass ShadersOOB : public ContextReset
748e5c31af7Sopenharmony_ci{
749e5c31af7Sopenharmony_cipublic:
750e5c31af7Sopenharmony_ci								ShadersOOB					(glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);
751e5c31af7Sopenharmony_ci								~ShadersOOB					(void);
752e5c31af7Sopenharmony_ci
753e5c31af7Sopenharmony_ci	virtual void				setup						(void);
754e5c31af7Sopenharmony_ci	virtual void				draw						(void);
755e5c31af7Sopenharmony_ci	virtual void				teardown					(void);
756e5c31af7Sopenharmony_ci
757e5c31af7Sopenharmony_ciprivate:
758e5c31af7Sopenharmony_ci	static const int			s_numBindings				= 3;
759e5c31af7Sopenharmony_ci
760e5c31af7Sopenharmony_ci	glw::GLuint					m_coordinatesBuffer;
761e5c31af7Sopenharmony_ci	glw::GLint					m_coordLocation;
762e5c31af7Sopenharmony_ci
763e5c31af7Sopenharmony_ci	bool						m_isUBO;
764e5c31af7Sopenharmony_ci	bool						m_isRead;
765e5c31af7Sopenharmony_ci	bool						m_isLocalArray;
766e5c31af7Sopenharmony_ci	std::vector<glw::GLuint>	m_buffers;
767e5c31af7Sopenharmony_ci
768e5c31af7Sopenharmony_ci	std::string					genVertexShader				(const std::string& shaderDecl, const std::string& shaderBody);
769e5c31af7Sopenharmony_ci	std::string					genFragmentShader			(const std::string& shaderDecl, const std::string& shaderBody);
770e5c31af7Sopenharmony_ci	std::string					genComputeShader			(const std::string& shaderDecl, const std::string& shaderBody);
771e5c31af7Sopenharmony_ci
772e5c31af7Sopenharmony_ci	glu::ProgramSources			genNonComputeSource			(void);
773e5c31af7Sopenharmony_ci	glu::ProgramSources			genComputeSource			(void);
774e5c31af7Sopenharmony_ci	glu::ProgramSources			genSources					(void);
775e5c31af7Sopenharmony_ci};
776e5c31af7Sopenharmony_ci
777e5c31af7Sopenharmony_ciShadersOOB::ShadersOOB (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
778e5c31af7Sopenharmony_ci	: ContextReset(gl, log, shaderType, resourceType, readWriteType)
779e5c31af7Sopenharmony_ci	, m_coordinatesBuffer	(0)
780e5c31af7Sopenharmony_ci	, m_coordLocation		(0)
781e5c31af7Sopenharmony_ci	, m_buffers				(s_numBindings, 0)
782e5c31af7Sopenharmony_ci{
783e5c31af7Sopenharmony_ci	m_isUBO			= (m_resourceType == RESOURCETYPE_UBO);
784e5c31af7Sopenharmony_ci	m_isLocalArray	= (m_resourceType == RESOURCETYPE_LOCAL_ARRAY);
785e5c31af7Sopenharmony_ci	m_isRead		= (m_readWriteType == READWRITETYPE_READ);
786e5c31af7Sopenharmony_ci}
787e5c31af7Sopenharmony_ci
788e5c31af7Sopenharmony_ciShadersOOB::~ShadersOOB (void)
789e5c31af7Sopenharmony_ci{
790e5c31af7Sopenharmony_ci	try
791e5c31af7Sopenharmony_ci	{
792e5c31af7Sopenharmony_ci		// Reset GL_CONTEXT_LOST error before destroying resources
793e5c31af7Sopenharmony_ci		m_gl.getGraphicsResetStatus();
794e5c31af7Sopenharmony_ci		teardown();
795e5c31af7Sopenharmony_ci	}
796e5c31af7Sopenharmony_ci	catch (...)
797e5c31af7Sopenharmony_ci	{
798e5c31af7Sopenharmony_ci		// Ignore GL errors from teardown()
799e5c31af7Sopenharmony_ci	}
800e5c31af7Sopenharmony_ci}
801e5c31af7Sopenharmony_ci
802e5c31af7Sopenharmony_cistd::string ShadersOOB::genVertexShader (const std::string& shaderDecl, const std::string& shaderBody)
803e5c31af7Sopenharmony_ci{
804e5c31af7Sopenharmony_ci	static const char* const s_simpleVertexShaderSource	=
805e5c31af7Sopenharmony_ci		"#version 310 es\n"
806e5c31af7Sopenharmony_ci		"in highp vec4 a_position;\n"
807e5c31af7Sopenharmony_ci		"void main (void)\n"
808e5c31af7Sopenharmony_ci		"{\n"
809e5c31af7Sopenharmony_ci		"	gl_Position = a_position;\n"
810e5c31af7Sopenharmony_ci		"}\n";
811e5c31af7Sopenharmony_ci
812e5c31af7Sopenharmony_ci	switch (m_shaderType)
813e5c31af7Sopenharmony_ci	{
814e5c31af7Sopenharmony_ci		case SHADERTYPE_VERT:
815e5c31af7Sopenharmony_ci		case SHADERTYPE_VERT_AND_FRAG:
816e5c31af7Sopenharmony_ci		{
817e5c31af7Sopenharmony_ci			std::ostringstream vertexShaderSource;
818e5c31af7Sopenharmony_ci			vertexShaderSource	<<	"#version 310 es\n"
819e5c31af7Sopenharmony_ci								<<	"in highp vec4 a_position;\n"
820e5c31af7Sopenharmony_ci								<<	"out highp vec4 v_color;\n"
821e5c31af7Sopenharmony_ci								<<	shaderDecl << "\n"
822e5c31af7Sopenharmony_ci								<<	"void main (void)\n"
823e5c31af7Sopenharmony_ci								<<	"{\n"
824e5c31af7Sopenharmony_ci								<<	"	highp vec4 color = vec4(0.0f);\n"
825e5c31af7Sopenharmony_ci								<<	shaderBody << "\n"
826e5c31af7Sopenharmony_ci								<<	"	v_color = color;\n"
827e5c31af7Sopenharmony_ci								<<	"	gl_Position = a_position;\n"
828e5c31af7Sopenharmony_ci								<<	"}\n";
829e5c31af7Sopenharmony_ci
830e5c31af7Sopenharmony_ci			return vertexShaderSource.str();
831e5c31af7Sopenharmony_ci		}
832e5c31af7Sopenharmony_ci
833e5c31af7Sopenharmony_ci		case SHADERTYPE_FRAG:
834e5c31af7Sopenharmony_ci			return s_simpleVertexShaderSource;
835e5c31af7Sopenharmony_ci
836e5c31af7Sopenharmony_ci		default:
837e5c31af7Sopenharmony_ci			DE_FATAL("Unknown shader type");
838e5c31af7Sopenharmony_ci			return "";
839e5c31af7Sopenharmony_ci	}
840e5c31af7Sopenharmony_ci}
841e5c31af7Sopenharmony_ci
842e5c31af7Sopenharmony_cistd::string ShadersOOB::genFragmentShader (const std::string& shaderDecl, const std::string& shaderBody)
843e5c31af7Sopenharmony_ci{
844e5c31af7Sopenharmony_ci	static const char* const s_simpleFragmentShaderSource =
845e5c31af7Sopenharmony_ci		"#version 310 es\n"
846e5c31af7Sopenharmony_ci		"in highp vec4 v_color;\n"
847e5c31af7Sopenharmony_ci		"layout(location = 0) out highp vec4 fragColor;\n"
848e5c31af7Sopenharmony_ci		"void main (void)\n"
849e5c31af7Sopenharmony_ci		"{\n"
850e5c31af7Sopenharmony_ci		"	fragColor = v_color;\n"
851e5c31af7Sopenharmony_ci		"}\n";
852e5c31af7Sopenharmony_ci
853e5c31af7Sopenharmony_ci	switch (m_shaderType)
854e5c31af7Sopenharmony_ci	{
855e5c31af7Sopenharmony_ci		case SHADERTYPE_VERT:
856e5c31af7Sopenharmony_ci			return s_simpleFragmentShaderSource;
857e5c31af7Sopenharmony_ci
858e5c31af7Sopenharmony_ci		case SHADERTYPE_FRAG:
859e5c31af7Sopenharmony_ci		{
860e5c31af7Sopenharmony_ci			std::ostringstream fragmentShaderSource;
861e5c31af7Sopenharmony_ci			fragmentShaderSource	<<	"#version 310 es\n"
862e5c31af7Sopenharmony_ci									<<	"layout(location = 0) out highp vec4 fragColor;\n"
863e5c31af7Sopenharmony_ci									<<	shaderDecl << "\n"
864e5c31af7Sopenharmony_ci									<<	"void main (void)\n"
865e5c31af7Sopenharmony_ci									<<	"{\n"
866e5c31af7Sopenharmony_ci									<<	"	highp vec4 color = vec4(0.0f);\n"
867e5c31af7Sopenharmony_ci									<<	shaderBody << "\n"
868e5c31af7Sopenharmony_ci									<<	"	fragColor = color;\n"
869e5c31af7Sopenharmony_ci									<<	"}\n";
870e5c31af7Sopenharmony_ci
871e5c31af7Sopenharmony_ci			return fragmentShaderSource.str();
872e5c31af7Sopenharmony_ci		}
873e5c31af7Sopenharmony_ci		case SHADERTYPE_VERT_AND_FRAG:
874e5c31af7Sopenharmony_ci		{
875e5c31af7Sopenharmony_ci			std::ostringstream fragmentShaderSource;
876e5c31af7Sopenharmony_ci			fragmentShaderSource	<<	"#version 310 es\n"
877e5c31af7Sopenharmony_ci									<<	"in highp vec4 v_color;\n"
878e5c31af7Sopenharmony_ci									<<	"layout(location = 0) out highp vec4 fragColor;\n"
879e5c31af7Sopenharmony_ci									<<	shaderDecl << "\n"
880e5c31af7Sopenharmony_ci									<<	"void main (void)\n"
881e5c31af7Sopenharmony_ci									<<	"{\n"
882e5c31af7Sopenharmony_ci									<<	"	highp vec4 color = vec4(0.0f);\n"
883e5c31af7Sopenharmony_ci									<<	shaderBody << "\n"
884e5c31af7Sopenharmony_ci									<<	"	fragColor = color;\n"
885e5c31af7Sopenharmony_ci									<<	"}\n";
886e5c31af7Sopenharmony_ci
887e5c31af7Sopenharmony_ci			return fragmentShaderSource.str();
888e5c31af7Sopenharmony_ci		}
889e5c31af7Sopenharmony_ci
890e5c31af7Sopenharmony_ci		default:
891e5c31af7Sopenharmony_ci			DE_FATAL("Unknown shader type");
892e5c31af7Sopenharmony_ci			return "";
893e5c31af7Sopenharmony_ci	}
894e5c31af7Sopenharmony_ci}
895e5c31af7Sopenharmony_ci
896e5c31af7Sopenharmony_cistd::string ShadersOOB::genComputeShader (const std::string& shaderDecl, const std::string& shaderBody)
897e5c31af7Sopenharmony_ci{
898e5c31af7Sopenharmony_ci	std::ostringstream computeShaderSource;
899e5c31af7Sopenharmony_ci
900e5c31af7Sopenharmony_ci	computeShaderSource		<<	"#version 310 es\n"
901e5c31af7Sopenharmony_ci							<<	"layout(local_size_x = 1, local_size_y = 1) in;\n"
902e5c31af7Sopenharmony_ci							<<	"\n"
903e5c31af7Sopenharmony_ci							<<	"layout(binding = 0) buffer Output {\n"
904e5c31af7Sopenharmony_ci							<<	"	highp vec4 values;\n"
905e5c31af7Sopenharmony_ci							<<	"} sb_out;\n"
906e5c31af7Sopenharmony_ci							<<	"\n"
907e5c31af7Sopenharmony_ci							<<	shaderDecl
908e5c31af7Sopenharmony_ci							<<	"void main ()\n"
909e5c31af7Sopenharmony_ci							<<	"{\n"
910e5c31af7Sopenharmony_ci							<<	shaderBody
911e5c31af7Sopenharmony_ci							<<	"}\n";
912e5c31af7Sopenharmony_ci
913e5c31af7Sopenharmony_ci	return computeShaderSource.str();
914e5c31af7Sopenharmony_ci}
915e5c31af7Sopenharmony_ci
916e5c31af7Sopenharmony_ciglu::ProgramSources ShadersOOB::genNonComputeSource (void)
917e5c31af7Sopenharmony_ci{
918e5c31af7Sopenharmony_ci	std::ostringstream		shaderDecl;
919e5c31af7Sopenharmony_ci	std::ostringstream		shaderBody;
920e5c31af7Sopenharmony_ci
921e5c31af7Sopenharmony_ci	shaderDecl << "uniform highp int u_index;\n";
922e5c31af7Sopenharmony_ci
923e5c31af7Sopenharmony_ci	if (m_isLocalArray)
924e5c31af7Sopenharmony_ci	{
925e5c31af7Sopenharmony_ci		const char* const readWriteStatement = (m_isRead)
926e5c31af7Sopenharmony_ci											 ? "	color.x = color_out[u_index];\n"
927e5c31af7Sopenharmony_ci											 : "	color[u_index] = color_out[0];\n";
928e5c31af7Sopenharmony_ci
929e5c31af7Sopenharmony_ci		shaderBody	<< "	highp float color_out[4] = float[4](0.25f, 0.5f, 0.75f, 1.0f);\n"
930e5c31af7Sopenharmony_ci					<< readWriteStatement;
931e5c31af7Sopenharmony_ci	}
932e5c31af7Sopenharmony_ci	else
933e5c31af7Sopenharmony_ci	{
934e5c31af7Sopenharmony_ci		const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
935e5c31af7Sopenharmony_ci
936e5c31af7Sopenharmony_ci		shaderDecl << "layout(std140, binding = 0) " << ((m_isUBO) ? "uniform" : "buffer") << " Block\n"
937e5c31af7Sopenharmony_ci			<< "{\n"
938e5c31af7Sopenharmony_ci			<< "	highp float color_out[4];\n"
939e5c31af7Sopenharmony_ci			<< "} " << resName << "[" << s_numBindings << "];\n";
940e5c31af7Sopenharmony_ci
941e5c31af7Sopenharmony_ci		const std::string readWriteStatement = (m_isRead)
942e5c31af7Sopenharmony_ci											 ? "	color.x = " + resName + "[0].color_out[u_index];\n"
943e5c31af7Sopenharmony_ci											 : "	color[u_index] = " + resName + "[0].color_out[0];\n";
944e5c31af7Sopenharmony_ci
945e5c31af7Sopenharmony_ci		shaderBody << readWriteStatement;
946e5c31af7Sopenharmony_ci	}
947e5c31af7Sopenharmony_ci
948e5c31af7Sopenharmony_ci	return glu::ProgramSources() << glu::VertexSource(genVertexShader(shaderDecl.str(), shaderBody.str()))
949e5c31af7Sopenharmony_ci								 << glu::FragmentSource(genFragmentShader(shaderDecl.str(), shaderBody.str()));
950e5c31af7Sopenharmony_ci}
951e5c31af7Sopenharmony_ci
952e5c31af7Sopenharmony_ciglu::ProgramSources ShadersOOB::genComputeSource (void)
953e5c31af7Sopenharmony_ci{
954e5c31af7Sopenharmony_ci	std::ostringstream		shaderDecl;
955e5c31af7Sopenharmony_ci	std::ostringstream		shaderBody;
956e5c31af7Sopenharmony_ci
957e5c31af7Sopenharmony_ci	shaderDecl << "uniform highp int u_index;\n";
958e5c31af7Sopenharmony_ci
959e5c31af7Sopenharmony_ci	shaderBody	<< "	uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
960e5c31af7Sopenharmony_ci				<< "	uint groupNdx = size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x;\n";
961e5c31af7Sopenharmony_ci
962e5c31af7Sopenharmony_ci	if (m_isLocalArray)
963e5c31af7Sopenharmony_ci	{
964e5c31af7Sopenharmony_ci		const char* const readWriteStatement = (m_isRead)
965e5c31af7Sopenharmony_ci											 ? "	sb_out.values.x = values[u_index];\n"
966e5c31af7Sopenharmony_ci											 : "	sb_out.values[u_index] = values.x;\n";
967e5c31af7Sopenharmony_ci
968e5c31af7Sopenharmony_ci		shaderBody	<< "	highp vec4 values = vec4(1.0f, 0.0f, 3.0f, 2.0f) * float(groupNdx);\n"
969e5c31af7Sopenharmony_ci					<< readWriteStatement;
970e5c31af7Sopenharmony_ci	}
971e5c31af7Sopenharmony_ci	else
972e5c31af7Sopenharmony_ci	{
973e5c31af7Sopenharmony_ci		const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
974e5c31af7Sopenharmony_ci
975e5c31af7Sopenharmony_ci		shaderDecl	<< "layout(std140, binding = 1) " << ((m_isUBO) ? "uniform" : "buffer") << " Input\n"
976e5c31af7Sopenharmony_ci					<< "{\n"
977e5c31af7Sopenharmony_ci					<< "	highp vec4 values;\n"
978e5c31af7Sopenharmony_ci					<< "} " << resName << "[" << s_numBindings << "];\n";
979e5c31af7Sopenharmony_ci
980e5c31af7Sopenharmony_ci		std::string readWriteStatement = (m_isRead)
981e5c31af7Sopenharmony_ci									   ? "	sb_out.values.x = " + resName + "[0].values[u_index] * float(groupNdx);\n"
982e5c31af7Sopenharmony_ci									   : "	sb_out.values[u_index] = " + resName + "[0].values.x * float(groupNdx);\n";
983e5c31af7Sopenharmony_ci
984e5c31af7Sopenharmony_ci		shaderBody << readWriteStatement;
985e5c31af7Sopenharmony_ci	}
986e5c31af7Sopenharmony_ci
987e5c31af7Sopenharmony_ci	return glu::ProgramSources() << glu::ComputeSource(genComputeShader(shaderDecl.str(), shaderBody.str()));
988e5c31af7Sopenharmony_ci}
989e5c31af7Sopenharmony_ci
990e5c31af7Sopenharmony_ciglu::ProgramSources ShadersOOB::genSources (void)
991e5c31af7Sopenharmony_ci{
992e5c31af7Sopenharmony_ci	if (m_shaderType == SHADERTYPE_COMPUTE)
993e5c31af7Sopenharmony_ci		return genComputeSource();
994e5c31af7Sopenharmony_ci	else
995e5c31af7Sopenharmony_ci		return genNonComputeSource();
996e5c31af7Sopenharmony_ci}
997e5c31af7Sopenharmony_ci
998e5c31af7Sopenharmony_civoid ShadersOOB::setup (void)
999e5c31af7Sopenharmony_ci{
1000e5c31af7Sopenharmony_ci	if (!m_isUBO && !m_isLocalArray && (m_shaderType != SHADERTYPE_COMPUTE))
1001e5c31af7Sopenharmony_ci	{
1002e5c31af7Sopenharmony_ci		// Check implementation limits for shader SSBO
1003e5c31af7Sopenharmony_ci		int shaderStorageBlockSupported = -1;
1004e5c31af7Sopenharmony_ci		const bool isVertex = (m_shaderType == SHADERTYPE_VERT || m_shaderType == SHADERTYPE_VERT_AND_FRAG) ? true : false;
1005e5c31af7Sopenharmony_ci		string shaderTypeStr = isVertex ? "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS" : "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS";
1006e5c31af7Sopenharmony_ci
1007e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, getIntegerv(isVertex ? GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS : GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &shaderStorageBlockSupported));
1008e5c31af7Sopenharmony_ci
1009e5c31af7Sopenharmony_ci		if (shaderStorageBlockSupported < (int)m_buffers.size())
1010e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, ("Test requires " + shaderTypeStr + " >= " + de::toString((int)m_buffers.size()) + ", got " + de::toString(shaderStorageBlockSupported)).c_str());
1011e5c31af7Sopenharmony_ci	}
1012e5c31af7Sopenharmony_ci
1013e5c31af7Sopenharmony_ci	glu::ShaderProgram program(m_gl, genSources());
1014e5c31af7Sopenharmony_ci
1015e5c31af7Sopenharmony_ci	m_log << program;
1016e5c31af7Sopenharmony_ci
1017e5c31af7Sopenharmony_ci	if (!program.isOk())
1018e5c31af7Sopenharmony_ci		TCU_FAIL("Failed to compile shader program");
1019e5c31af7Sopenharmony_ci
1020e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
1021e5c31af7Sopenharmony_ci
1022e5c31af7Sopenharmony_ci	const glw::GLint indexLocation = m_gl.getUniformLocation(program.getProgram(), "u_index");
1023e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
1024e5c31af7Sopenharmony_ci	TCU_CHECK(indexLocation != (glw::GLint)-1);
1025e5c31af7Sopenharmony_ci
1026e5c31af7Sopenharmony_ci	const glw::GLint index = -1;
1027e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, uniform1i(indexLocation, index));
1028e5c31af7Sopenharmony_ci
1029e5c31af7Sopenharmony_ci	if (m_shaderType != SHADERTYPE_COMPUTE)
1030e5c31af7Sopenharmony_ci	{
1031e5c31af7Sopenharmony_ci		const glw::GLfloat coords[] =
1032e5c31af7Sopenharmony_ci		{
1033e5c31af7Sopenharmony_ci			-1.0f, -1.0f,
1034e5c31af7Sopenharmony_ci			+1.0f, -1.0f,
1035e5c31af7Sopenharmony_ci			+1.0f, +1.0f,
1036e5c31af7Sopenharmony_ci			-1.0f, +1.0f
1037e5c31af7Sopenharmony_ci		};
1038e5c31af7Sopenharmony_ci
1039e5c31af7Sopenharmony_ci		// Setup vertices position
1040e5c31af7Sopenharmony_ci		m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
1041e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
1042e5c31af7Sopenharmony_ci		TCU_CHECK(m_coordLocation != (glw::GLint)-1);
1043e5c31af7Sopenharmony_ci
1044e5c31af7Sopenharmony_ci		// Load the vertex data
1045e5c31af7Sopenharmony_ci		m_coordinatesBuffer = 0;
1046e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
1047e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
1048e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
1049e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
1050e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
1051e5c31af7Sopenharmony_ci	}
1052e5c31af7Sopenharmony_ci
1053e5c31af7Sopenharmony_ci	// Create unused data for filling buffer objects
1054e5c31af7Sopenharmony_ci	const std::vector<tcu::Vec4> refValues(s_numBindings, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
1055e5c31af7Sopenharmony_ci
1056e5c31af7Sopenharmony_ci	if (m_isLocalArray && m_shaderType == SHADERTYPE_COMPUTE)
1057e5c31af7Sopenharmony_ci	{
1058e5c31af7Sopenharmony_ci		// Setup output buffer
1059e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)1u, &m_buffers[0]));
1060e5c31af7Sopenharmony_ci
1061e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[0]));
1062e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(tcu::Vec4), &(refValues[0]), GL_STATIC_DRAW));
1063e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffers[0]));
1064e5c31af7Sopenharmony_ci	}
1065e5c31af7Sopenharmony_ci	else if (!m_isLocalArray)
1066e5c31af7Sopenharmony_ci	{
1067e5c31af7Sopenharmony_ci		// Set up interface block of buffer bindings
1068e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
1069e5c31af7Sopenharmony_ci
1070e5c31af7Sopenharmony_ci		for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1071e5c31af7Sopenharmony_ci		{
1072e5c31af7Sopenharmony_ci			const glw::GLenum resType	= m_isUBO && (m_shaderType != SHADERTYPE_COMPUTE || bufNdx != 0)
1073e5c31af7Sopenharmony_ci										? GL_UNIFORM_BUFFER
1074e5c31af7Sopenharmony_ci										: GL_SHADER_STORAGE_BUFFER;
1075e5c31af7Sopenharmony_ci
1076e5c31af7Sopenharmony_ci			GLU_CHECK_GLW_CALL(m_gl, bindBuffer(resType, m_buffers[bufNdx]));
1077e5c31af7Sopenharmony_ci			GLU_CHECK_GLW_CALL(m_gl, bufferData(resType, sizeof(tcu::Vec4), &(refValues[bufNdx]), GL_STATIC_DRAW));
1078e5c31af7Sopenharmony_ci			GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(resType, bufNdx, m_buffers[bufNdx]));
1079e5c31af7Sopenharmony_ci		}
1080e5c31af7Sopenharmony_ci	}
1081e5c31af7Sopenharmony_ci}
1082e5c31af7Sopenharmony_ci
1083e5c31af7Sopenharmony_civoid ShadersOOB::draw (void)
1084e5c31af7Sopenharmony_ci{
1085e5c31af7Sopenharmony_ci	if (m_shaderType == SHADERTYPE_COMPUTE)
1086e5c31af7Sopenharmony_ci		m_gl.dispatchCompute(1, 1, 1);
1087e5c31af7Sopenharmony_ci	else
1088e5c31af7Sopenharmony_ci	{
1089e5c31af7Sopenharmony_ci		const glw::GLuint indices[] = {0, 1, 2, 2, 3, 0};
1090e5c31af7Sopenharmony_ci		m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
1091e5c31af7Sopenharmony_ci	}
1092e5c31af7Sopenharmony_ci}
1093e5c31af7Sopenharmony_ci
1094e5c31af7Sopenharmony_civoid ShadersOOB::teardown (void)
1095e5c31af7Sopenharmony_ci{
1096e5c31af7Sopenharmony_ci	if (m_shaderType != SHADERTYPE_COMPUTE)
1097e5c31af7Sopenharmony_ci	{
1098e5c31af7Sopenharmony_ci		if (m_coordLocation)
1099e5c31af7Sopenharmony_ci		{
1100e5c31af7Sopenharmony_ci			GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
1101e5c31af7Sopenharmony_ci			m_coordLocation = 0;
1102e5c31af7Sopenharmony_ci		}
1103e5c31af7Sopenharmony_ci	}
1104e5c31af7Sopenharmony_ci
1105e5c31af7Sopenharmony_ci	if (m_coordinatesBuffer)
1106e5c31af7Sopenharmony_ci	{
1107e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
1108e5c31af7Sopenharmony_ci		m_coordinatesBuffer = 0;
1109e5c31af7Sopenharmony_ci	}
1110e5c31af7Sopenharmony_ci
1111e5c31af7Sopenharmony_ci	if (!m_isLocalArray)
1112e5c31af7Sopenharmony_ci	{
1113e5c31af7Sopenharmony_ci		if (!m_buffers.empty())
1114e5c31af7Sopenharmony_ci		{
1115e5c31af7Sopenharmony_ci			GLU_CHECK_GLW_CALL(m_gl, deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
1116e5c31af7Sopenharmony_ci			m_buffers.clear();
1117e5c31af7Sopenharmony_ci		}
1118e5c31af7Sopenharmony_ci	}
1119e5c31af7Sopenharmony_ci
1120e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
1121e5c31af7Sopenharmony_ci}
1122e5c31af7Sopenharmony_ci
1123e5c31af7Sopenharmony_ciclass QueryRobustAccessCase : public RobustnessTestCase
1124e5c31af7Sopenharmony_ci{
1125e5c31af7Sopenharmony_cipublic:
1126e5c31af7Sopenharmony_ci	QueryRobustAccessCase (EglTestContext& eglTestCtx, const char* name, const char* description)
1127e5c31af7Sopenharmony_ci		: RobustnessTestCase (eglTestCtx, name, description) {}
1128e5c31af7Sopenharmony_ci
1129e5c31af7Sopenharmony_ci	TestCase::IterateResult	iterate		(void)
1130e5c31af7Sopenharmony_ci	{
1131e5c31af7Sopenharmony_ci		TestLog&	log		= m_testCtx.getLog();
1132e5c31af7Sopenharmony_ci
1133e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message
1134e5c31af7Sopenharmony_ci			<< "Check that after successfully creating a robust context the robust access query returned by glBooleanv() equals GL_TRUE\n\n"
1135e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
1136e5c31af7Sopenharmony_ci
1137e5c31af7Sopenharmony_ci		const EGLint attribList[] =
1138e5c31af7Sopenharmony_ci		{
1139e5c31af7Sopenharmony_ci			EGL_CONTEXT_CLIENT_VERSION, 3,
1140e5c31af7Sopenharmony_ci			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
1141e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
1142e5c31af7Sopenharmony_ci			EGL_NONE
1143e5c31af7Sopenharmony_ci		};
1144e5c31af7Sopenharmony_ci
1145e5c31af7Sopenharmony_ci		checkRequiredEGLExtensions(attribList);
1146e5c31af7Sopenharmony_ci
1147e5c31af7Sopenharmony_ci		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1148e5c31af7Sopenharmony_ci		context.makeCurrent(m_eglSurface);
1149e5c31af7Sopenharmony_ci
1150e5c31af7Sopenharmony_ci		glw::Functions gl;
1151e5c31af7Sopenharmony_ci		{
1152e5c31af7Sopenharmony_ci			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
1153e5c31af7Sopenharmony_ci			context.initGLFunctions(&gl, apiType);
1154e5c31af7Sopenharmony_ci			checkRequiredGLSupport(gl, apiType);
1155e5c31af7Sopenharmony_ci		}
1156e5c31af7Sopenharmony_ci
1157e5c31af7Sopenharmony_ci		deUint8 robustAccessGL;
1158e5c31af7Sopenharmony_ci		gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
1159e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
1160e5c31af7Sopenharmony_ci
1161e5c31af7Sopenharmony_ci		if (robustAccessGL != GL_TRUE)
1162e5c31af7Sopenharmony_ci		{
1163e5c31af7Sopenharmony_ci			log << TestLog::Message
1164e5c31af7Sopenharmony_ci				<< "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '" << robustAccessGL << "' expected GL_TRUE."
1165e5c31af7Sopenharmony_ci				<< TestLog::EndMessage;
1166e5c31af7Sopenharmony_ci
1167e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1168e5c31af7Sopenharmony_ci			return STOP;
1169e5c31af7Sopenharmony_ci		}
1170e5c31af7Sopenharmony_ci
1171e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1172e5c31af7Sopenharmony_ci		return STOP;
1173e5c31af7Sopenharmony_ci	}
1174e5c31af7Sopenharmony_ci};
1175e5c31af7Sopenharmony_ci
1176e5c31af7Sopenharmony_ciclass NoResetNotificationCase : public RobustnessTestCase
1177e5c31af7Sopenharmony_ci{
1178e5c31af7Sopenharmony_cipublic:
1179e5c31af7Sopenharmony_ci	NoResetNotificationCase (EglTestContext& eglTestCtx, const char* name, const char* description)
1180e5c31af7Sopenharmony_ci		: RobustnessTestCase (eglTestCtx, name, description) {}
1181e5c31af7Sopenharmony_ci
1182e5c31af7Sopenharmony_ci	TestCase::IterateResult	iterate		(void)
1183e5c31af7Sopenharmony_ci	{
1184e5c31af7Sopenharmony_ci		TestLog&	log		= m_testCtx.getLog();
1185e5c31af7Sopenharmony_ci
1186e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message
1187e5c31af7Sopenharmony_ci			<< "Check the reset notification strategy returned by glGetIntegerv() equals GL_NO_RESET_NOTIFICATION\n\n"
1188e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
1189e5c31af7Sopenharmony_ci
1190e5c31af7Sopenharmony_ci		const EGLint attribList[] =
1191e5c31af7Sopenharmony_ci		{
1192e5c31af7Sopenharmony_ci			EGL_CONTEXT_CLIENT_VERSION, 3,
1193e5c31af7Sopenharmony_ci			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
1194e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
1195e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
1196e5c31af7Sopenharmony_ci			EGL_NONE
1197e5c31af7Sopenharmony_ci		};
1198e5c31af7Sopenharmony_ci
1199e5c31af7Sopenharmony_ci		checkRequiredEGLExtensions(attribList);
1200e5c31af7Sopenharmony_ci
1201e5c31af7Sopenharmony_ci		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1202e5c31af7Sopenharmony_ci		context.makeCurrent(m_eglSurface);
1203e5c31af7Sopenharmony_ci
1204e5c31af7Sopenharmony_ci		glw::Functions gl;
1205e5c31af7Sopenharmony_ci		{
1206e5c31af7Sopenharmony_ci			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
1207e5c31af7Sopenharmony_ci			context.initGLFunctions(&gl, apiType);
1208e5c31af7Sopenharmony_ci			checkRequiredGLSupport(gl, apiType);
1209e5c31af7Sopenharmony_ci		}
1210e5c31af7Sopenharmony_ci
1211e5c31af7Sopenharmony_ci		deUint8 robustAccessGL;
1212e5c31af7Sopenharmony_ci		gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
1213e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
1214e5c31af7Sopenharmony_ci
1215e5c31af7Sopenharmony_ci		glw::GLint reset = 0;
1216e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
1217e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
1218e5c31af7Sopenharmony_ci
1219e5c31af7Sopenharmony_ci		if (reset != GL_NO_RESET_NOTIFICATION)
1220e5c31af7Sopenharmony_ci		{
1221e5c31af7Sopenharmony_ci			log	<< tcu::TestLog::Message
1222e5c31af7Sopenharmony_ci				<< "Test failed! glGetIntegerv() returned wrong value. [" << glu::getErrorStr(reset) << ", expected " << glu::getErrorStr(GL_NO_RESET_NOTIFICATION) << "]"
1223e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
1224e5c31af7Sopenharmony_ci
1225e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1226e5c31af7Sopenharmony_ci			return STOP;
1227e5c31af7Sopenharmony_ci		}
1228e5c31af7Sopenharmony_ci
1229e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
1230e5c31af7Sopenharmony_ci
1231e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1232e5c31af7Sopenharmony_ci		return STOP;
1233e5c31af7Sopenharmony_ci	}
1234e5c31af7Sopenharmony_ci};
1235e5c31af7Sopenharmony_ci
1236e5c31af7Sopenharmony_ciclass LoseContextOnResetCase : public RobustnessTestCase
1237e5c31af7Sopenharmony_ci{
1238e5c31af7Sopenharmony_cipublic:
1239e5c31af7Sopenharmony_ci	LoseContextOnResetCase (EglTestContext& eglTestCtx, const char* name, const char* description)
1240e5c31af7Sopenharmony_ci		: RobustnessTestCase(eglTestCtx, name, description) {}
1241e5c31af7Sopenharmony_ci
1242e5c31af7Sopenharmony_ci	TestCase::IterateResult	iterate		(void)
1243e5c31af7Sopenharmony_ci	{
1244e5c31af7Sopenharmony_ci		TestLog&	log		= m_testCtx.getLog();
1245e5c31af7Sopenharmony_ci
1246e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message
1247e5c31af7Sopenharmony_ci			<< "Check the reset notification strategy returned by glGetIntegerv() equals GL_LOSE_CONTEXT_ON_RESET\n\n"
1248e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
1249e5c31af7Sopenharmony_ci
1250e5c31af7Sopenharmony_ci		const EGLint attribList[] =
1251e5c31af7Sopenharmony_ci		{
1252e5c31af7Sopenharmony_ci			EGL_CONTEXT_CLIENT_VERSION, 3,
1253e5c31af7Sopenharmony_ci			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
1254e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
1255e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
1256e5c31af7Sopenharmony_ci			EGL_NONE
1257e5c31af7Sopenharmony_ci		};
1258e5c31af7Sopenharmony_ci
1259e5c31af7Sopenharmony_ci		checkRequiredEGLExtensions(attribList);
1260e5c31af7Sopenharmony_ci
1261e5c31af7Sopenharmony_ci		RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1262e5c31af7Sopenharmony_ci		context.makeCurrent(m_eglSurface);
1263e5c31af7Sopenharmony_ci
1264e5c31af7Sopenharmony_ci		glw::Functions gl;
1265e5c31af7Sopenharmony_ci		{
1266e5c31af7Sopenharmony_ci			const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
1267e5c31af7Sopenharmony_ci			context.initGLFunctions(&gl, apiType);
1268e5c31af7Sopenharmony_ci			checkRequiredGLSupport(gl, apiType);
1269e5c31af7Sopenharmony_ci		}
1270e5c31af7Sopenharmony_ci		glw::GLint reset = 0;
1271e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
1272e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
1273e5c31af7Sopenharmony_ci
1274e5c31af7Sopenharmony_ci		if (reset != GL_LOSE_CONTEXT_ON_RESET)
1275e5c31af7Sopenharmony_ci		{
1276e5c31af7Sopenharmony_ci			log	<< tcu::TestLog::Message
1277e5c31af7Sopenharmony_ci				<< "Test failed! glGetIntegerv() returned wrong value. [" << reset << ", expected " << glu::getErrorStr(GL_LOSE_CONTEXT_ON_RESET) << "]"
1278e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
1279e5c31af7Sopenharmony_ci
1280e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1281e5c31af7Sopenharmony_ci			return STOP;
1282e5c31af7Sopenharmony_ci		}
1283e5c31af7Sopenharmony_ci
1284e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message
1285e5c31af7Sopenharmony_ci			<< "Check the graphics reset status returned by glGetGraphicsResetStatus() "
1286e5c31af7Sopenharmony_ci			<< "equals GL_NO_ERROR\n"
1287e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
1288e5c31af7Sopenharmony_ci
1289e5c31af7Sopenharmony_ci		GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
1290e5c31af7Sopenharmony_ci
1291e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1292e5c31af7Sopenharmony_ci		return STOP;
1293e5c31af7Sopenharmony_ci	}
1294e5c31af7Sopenharmony_ci};
1295e5c31af7Sopenharmony_ci
1296e5c31af7Sopenharmony_cide::SharedPtr<ContextReset> contextResetFactory (const RobustnessTestCase::Params params, glw::Functions& gl, tcu::TestLog& log)
1297e5c31af7Sopenharmony_ci{
1298e5c31af7Sopenharmony_ci	if (params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
1299e5c31af7Sopenharmony_ci		return de::SharedPtr<ContextReset>(new FixedFunctionOOB(gl, log, params.getFixedFunctionType()));
1300e5c31af7Sopenharmony_ci
1301e5c31af7Sopenharmony_ci	if (params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
1302e5c31af7Sopenharmony_ci		return de::SharedPtr<ContextReset>(new ShadersOOB(gl, log, params.getShaderType(), params.getResourceType(), params.getReadWriteType()));
1303e5c31af7Sopenharmony_ci	else
1304e5c31af7Sopenharmony_ci	{
1305e5c31af7Sopenharmony_ci		DE_FATAL("Unknown context reset type");
1306e5c31af7Sopenharmony_ci		return de::SharedPtr<ContextReset>(DE_NULL);
1307e5c31af7Sopenharmony_ci	}
1308e5c31af7Sopenharmony_ci}
1309e5c31af7Sopenharmony_ci
1310e5c31af7Sopenharmony_ciclass ContextResetCase : public RobustnessTestCase
1311e5c31af7Sopenharmony_ci{
1312e5c31af7Sopenharmony_ci
1313e5c31af7Sopenharmony_cipublic:
1314e5c31af7Sopenharmony_ci							ContextResetCase		(EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
1315e5c31af7Sopenharmony_ci	virtual					~ContextResetCase		(void) {}
1316e5c31af7Sopenharmony_ci
1317e5c31af7Sopenharmony_ci	virtual void			provokeReset			(de::SharedPtr<ContextReset>& contextReset) = 0;
1318e5c31af7Sopenharmony_ci	virtual void			waitForReset			(de::SharedPtr<ContextReset>& contextReset) = 0;
1319e5c31af7Sopenharmony_ci	virtual void			passAndLog				(de::SharedPtr<ContextReset>& contextReset) = 0;
1320e5c31af7Sopenharmony_ci
1321e5c31af7Sopenharmony_ci	TestCase::IterateResult iterate					(void);
1322e5c31af7Sopenharmony_ci	void					execute					(glw::Functions& gl);
1323e5c31af7Sopenharmony_ci
1324e5c31af7Sopenharmony_ciprivate:
1325e5c31af7Sopenharmony_ci						ContextResetCase			(const ContextResetCase&);
1326e5c31af7Sopenharmony_ci	ContextResetCase&	operator=					(const ContextResetCase&);
1327e5c31af7Sopenharmony_ci};
1328e5c31af7Sopenharmony_ci
1329e5c31af7Sopenharmony_ciContextResetCase::ContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
1330e5c31af7Sopenharmony_ci	: RobustnessTestCase (eglTestCtx, name, description, params) {}
1331e5c31af7Sopenharmony_ci
1332e5c31af7Sopenharmony_ciTestCase::IterateResult ContextResetCase::iterate (void)
1333e5c31af7Sopenharmony_ci{
1334e5c31af7Sopenharmony_ci	glw::Functions	gl;
1335e5c31af7Sopenharmony_ci
1336e5c31af7Sopenharmony_ci	const EGLint attribList[] =
1337e5c31af7Sopenharmony_ci	{
1338e5c31af7Sopenharmony_ci		EGL_CONTEXT_CLIENT_VERSION, 3,
1339e5c31af7Sopenharmony_ci		EGL_CONTEXT_MINOR_VERSION_KHR, 0,
1340e5c31af7Sopenharmony_ci		EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, (m_params.getRobustAccessType() == ROBUSTACCESS_TRUE) ? EGL_TRUE : EGL_FALSE,
1341e5c31af7Sopenharmony_ci		EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
1342e5c31af7Sopenharmony_ci		EGL_NONE
1343e5c31af7Sopenharmony_ci	};
1344e5c31af7Sopenharmony_ci
1345e5c31af7Sopenharmony_ci	checkRequiredEGLExtensions(attribList);
1346e5c31af7Sopenharmony_ci
1347e5c31af7Sopenharmony_ci	RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1348e5c31af7Sopenharmony_ci	context.makeCurrent(m_eglSurface);
1349e5c31af7Sopenharmony_ci
1350e5c31af7Sopenharmony_ci	{
1351e5c31af7Sopenharmony_ci		const glu::ApiType apiType = paramsToApiType(m_params);
1352e5c31af7Sopenharmony_ci		context.initGLFunctions(&gl, apiType);
1353e5c31af7Sopenharmony_ci		checkGLSupportForParams(gl, m_params);
1354e5c31af7Sopenharmony_ci	}
1355e5c31af7Sopenharmony_ci
1356e5c31af7Sopenharmony_ci	execute(gl);
1357e5c31af7Sopenharmony_ci
1358e5c31af7Sopenharmony_ci	return STOP;
1359e5c31af7Sopenharmony_ci}
1360e5c31af7Sopenharmony_ci
1361e5c31af7Sopenharmony_civoid ContextResetCase::execute (glw::Functions& gl)
1362e5c31af7Sopenharmony_ci{
1363e5c31af7Sopenharmony_ci	de::SharedPtr<ContextReset> contextReset					= contextResetFactory(m_params, gl, m_testCtx.getLog());
1364e5c31af7Sopenharmony_ci	glw::GLboolean				isContextRobust					= GL_FALSE;
1365e5c31af7Sopenharmony_ci
1366e5c31af7Sopenharmony_ci	GLU_CHECK_GLW_CALL(gl, getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &isContextRobust));
1367e5c31af7Sopenharmony_ci	provokeReset(contextReset);
1368e5c31af7Sopenharmony_ci
1369e5c31af7Sopenharmony_ci	if (m_params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB || m_params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
1370e5c31af7Sopenharmony_ci	{
1371e5c31af7Sopenharmony_ci		try
1372e5c31af7Sopenharmony_ci		{
1373e5c31af7Sopenharmony_ci			waitForReset(contextReset);
1374e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was NOT lost. Test skipped");
1375e5c31af7Sopenharmony_ci		}
1376e5c31af7Sopenharmony_ci		catch (const glu::Error& error)
1377e5c31af7Sopenharmony_ci		{
1378e5c31af7Sopenharmony_ci			if (error.getError() == GL_CONTEXT_LOST)
1379e5c31af7Sopenharmony_ci			{
1380e5c31af7Sopenharmony_ci				if (isContextRobust)
1381e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "No context reset should of occurred GL_CONTEXT_ROBUST_ACCESS == TRUE");
1382e5c31af7Sopenharmony_ci				else
1383e5c31af7Sopenharmony_ci					passAndLog(contextReset);
1384e5c31af7Sopenharmony_ci			}
1385e5c31af7Sopenharmony_ci			else if (isContextRobust)
1386e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unknown error.");
1387e5c31af7Sopenharmony_ci			else
1388e5c31af7Sopenharmony_ci			{
1389e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Warning: glGetError() returned wrong value. Expected GL_CONTEXT_LOST");
1390e5c31af7Sopenharmony_ci
1391e5c31af7Sopenharmony_ci				m_testCtx.getLog()	<< tcu::TestLog::Message
1392e5c31af7Sopenharmony_ci									<< "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
1393e5c31af7Sopenharmony_ci									<< tcu::TestLog::EndMessage;
1394e5c31af7Sopenharmony_ci			}
1395e5c31af7Sopenharmony_ci		}
1396e5c31af7Sopenharmony_ci	}
1397e5c31af7Sopenharmony_ci	else
1398e5c31af7Sopenharmony_ci		DE_FATAL("Unknown context reset type");
1399e5c31af7Sopenharmony_ci}
1400e5c31af7Sopenharmony_ci
1401e5c31af7Sopenharmony_ciclass BasicResetCase : public ContextResetCase
1402e5c31af7Sopenharmony_ci{
1403e5c31af7Sopenharmony_cipublic:
1404e5c31af7Sopenharmony_ci
1405e5c31af7Sopenharmony_ci	BasicResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
1406e5c31af7Sopenharmony_ci		: ContextResetCase (eglTestCtx, name, description, params) {}
1407e5c31af7Sopenharmony_ci
1408e5c31af7Sopenharmony_ci	virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
1409e5c31af7Sopenharmony_ci	{
1410e5c31af7Sopenharmony_ci		m_testCtx.getLog()	<< tcu::TestLog::Message
1411e5c31af7Sopenharmony_ci							<< "Check the graphics reset status returned by glGetGraphicsResetStatus() equals "
1412e5c31af7Sopenharmony_ci							<< "GL_GUILTY_CONTEXT_RESET after a context reset\n\n"
1413e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage;
1414e5c31af7Sopenharmony_ci
1415e5c31af7Sopenharmony_ci		contextReset->setup();
1416e5c31af7Sopenharmony_ci		contextReset->draw();
1417e5c31af7Sopenharmony_ci	}
1418e5c31af7Sopenharmony_ci
1419e5c31af7Sopenharmony_ci	virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
1420e5c31af7Sopenharmony_ci	{
1421e5c31af7Sopenharmony_ci		contextReset->teardown();
1422e5c31af7Sopenharmony_ci		contextReset->finish();
1423e5c31af7Sopenharmony_ci	}
1424e5c31af7Sopenharmony_ci
1425e5c31af7Sopenharmony_ci	virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
1426e5c31af7Sopenharmony_ci	{
1427e5c31af7Sopenharmony_ci		const glw::GLint status = contextReset->getGraphicsResetStatus();
1428e5c31af7Sopenharmony_ci
1429e5c31af7Sopenharmony_ci		if (status == GL_NO_ERROR)
1430e5c31af7Sopenharmony_ci		{
1431e5c31af7Sopenharmony_ci			m_testCtx.getLog()	<< tcu::TestLog::Message
1432e5c31af7Sopenharmony_ci								<< "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getGraphicsResetStatusStr(status) << ", expected " << glu::getGraphicsResetStatusStr(GL_GUILTY_CONTEXT_RESET) << "]"
1433e5c31af7Sopenharmony_ci								<< tcu::TestLog::EndMessage;
1434e5c31af7Sopenharmony_ci
1435e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1436e5c31af7Sopenharmony_ci		}
1437e5c31af7Sopenharmony_ci		else
1438e5c31af7Sopenharmony_ci		{
1439e5c31af7Sopenharmony_ci			if (contextReset->getError() != GL_NO_ERROR)
1440e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error flag not reset after calling getGraphicsResetStatus()");
1441e5c31af7Sopenharmony_ci			else
1442e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1443e5c31af7Sopenharmony_ci		}
1444e5c31af7Sopenharmony_ci	}
1445e5c31af7Sopenharmony_ci};
1446e5c31af7Sopenharmony_ci
1447e5c31af7Sopenharmony_ciclass InvalidShareContextCase : public RobustnessTestCase
1448e5c31af7Sopenharmony_ci{
1449e5c31af7Sopenharmony_cipublic:
1450e5c31af7Sopenharmony_ci	InvalidShareContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
1451e5c31af7Sopenharmony_ci		: RobustnessTestCase (eglTestCtx, name, description) {}
1452e5c31af7Sopenharmony_ci
1453e5c31af7Sopenharmony_ci	TestCase::IterateResult	iterate	(void)
1454e5c31af7Sopenharmony_ci	{
1455e5c31af7Sopenharmony_ci		TestLog&		log		=	m_testCtx.getLog();
1456e5c31af7Sopenharmony_ci		const Library&	egl		=	m_eglTestCtx.getLibrary();
1457e5c31af7Sopenharmony_ci		bool			isOk	=	true;
1458e5c31af7Sopenharmony_ci
1459e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message
1460e5c31af7Sopenharmony_ci			<< "EGL_BAD_MATCH is generated if reset notification strategies do not match when creating shared contexts\n\n"
1461e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
1462e5c31af7Sopenharmony_ci
1463e5c31af7Sopenharmony_ci		const EGLint attribListA[] =
1464e5c31af7Sopenharmony_ci		{
1465e5c31af7Sopenharmony_ci			EGL_CONTEXT_CLIENT_VERSION, 3,
1466e5c31af7Sopenharmony_ci			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
1467e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
1468e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
1469e5c31af7Sopenharmony_ci			EGL_NONE
1470e5c31af7Sopenharmony_ci		};
1471e5c31af7Sopenharmony_ci
1472e5c31af7Sopenharmony_ci		const EGLint attribListB[] =
1473e5c31af7Sopenharmony_ci		{
1474e5c31af7Sopenharmony_ci			EGL_CONTEXT_CLIENT_VERSION, 3,
1475e5c31af7Sopenharmony_ci			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
1476e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
1477e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
1478e5c31af7Sopenharmony_ci			EGL_NONE
1479e5c31af7Sopenharmony_ci		};
1480e5c31af7Sopenharmony_ci
1481e5c31af7Sopenharmony_ci		checkRequiredEGLExtensions(attribListA);
1482e5c31af7Sopenharmony_ci
1483e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
1484e5c31af7Sopenharmony_ci		RenderingContext contextA(m_eglTestCtx, attribListA, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1485e5c31af7Sopenharmony_ci
1486e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
1487e5c31af7Sopenharmony_ci		logAttribList(m_eglTestCtx, attribListB);
1488e5c31af7Sopenharmony_ci
1489e5c31af7Sopenharmony_ci		EGLContext contextB = egl.createContext(m_eglDisplay, m_eglConfig, contextA.getContext(), attribListB);
1490e5c31af7Sopenharmony_ci
1491e5c31af7Sopenharmony_ci		const EGLenum error = egl.getError();
1492e5c31af7Sopenharmony_ci		if (error != EGL_BAD_MATCH)
1493e5c31af7Sopenharmony_ci		{
1494e5c31af7Sopenharmony_ci			log << TestLog::Message
1495e5c31af7Sopenharmony_ci				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_MATCH) << "]"
1496e5c31af7Sopenharmony_ci				<< TestLog::EndMessage;
1497e5c31af7Sopenharmony_ci
1498e5c31af7Sopenharmony_ci			isOk = false;
1499e5c31af7Sopenharmony_ci		}
1500e5c31af7Sopenharmony_ci
1501e5c31af7Sopenharmony_ci		if (contextB != EGL_NO_CONTEXT)
1502e5c31af7Sopenharmony_ci			egl.destroyContext(m_eglDisplay, contextB);
1503e5c31af7Sopenharmony_ci
1504e5c31af7Sopenharmony_ci		if (isOk)
1505e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1506e5c31af7Sopenharmony_ci		else
1507e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1508e5c31af7Sopenharmony_ci
1509e5c31af7Sopenharmony_ci		return STOP;
1510e5c31af7Sopenharmony_ci	}
1511e5c31af7Sopenharmony_ci};
1512e5c31af7Sopenharmony_ci
1513e5c31af7Sopenharmony_ciclass InvalidNotificationEnumCase : public RobustnessTestCase
1514e5c31af7Sopenharmony_ci{
1515e5c31af7Sopenharmony_cipublic:
1516e5c31af7Sopenharmony_ci	InvalidNotificationEnumCase (EglTestContext& eglTestCtx, const char* name, const char* description)
1517e5c31af7Sopenharmony_ci		: RobustnessTestCase (eglTestCtx, name, description) {}
1518e5c31af7Sopenharmony_ci
1519e5c31af7Sopenharmony_ci	TestCase::IterateResult	iterate	(void)
1520e5c31af7Sopenharmony_ci	{
1521e5c31af7Sopenharmony_ci		TestLog&		log		=	m_testCtx.getLog();
1522e5c31af7Sopenharmony_ci		const Library&	egl		=	m_eglTestCtx.getLibrary();
1523e5c31af7Sopenharmony_ci		bool			isOk	=	true;
1524e5c31af7Sopenharmony_ci
1525e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message
1526e5c31af7Sopenharmony_ci			<< "EGL_BAD_ATTRIBUTE is generated if EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR is used with EGL versions <= 1.4\n\n"
1527e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
1528e5c31af7Sopenharmony_ci
1529e5c31af7Sopenharmony_ci		const EGLint attribList[] =
1530e5c31af7Sopenharmony_ci		{
1531e5c31af7Sopenharmony_ci			EGL_CONTEXT_CLIENT_VERSION, 3,
1532e5c31af7Sopenharmony_ci			EGL_CONTEXT_MINOR_VERSION_KHR, 1,
1533e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_NO_RESET_NOTIFICATION,
1534e5c31af7Sopenharmony_ci			EGL_NONE
1535e5c31af7Sopenharmony_ci		};
1536e5c31af7Sopenharmony_ci
1537e5c31af7Sopenharmony_ci		if (eglu::getVersion(egl, m_eglDisplay) >= eglu::Version(1, 5))
1538e5c31af7Sopenharmony_ci		{
1539e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL version to be under 1.5");
1540e5c31af7Sopenharmony_ci			return STOP;
1541e5c31af7Sopenharmony_ci		}
1542e5c31af7Sopenharmony_ci
1543e5c31af7Sopenharmony_ci		logAttribList(m_eglTestCtx, attribList);
1544e5c31af7Sopenharmony_ci		EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
1545e5c31af7Sopenharmony_ci
1546e5c31af7Sopenharmony_ci		const EGLenum error = egl.getError();
1547e5c31af7Sopenharmony_ci		if (error != EGL_BAD_ATTRIBUTE)
1548e5c31af7Sopenharmony_ci		{
1549e5c31af7Sopenharmony_ci			log << TestLog::Message
1550e5c31af7Sopenharmony_ci				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
1551e5c31af7Sopenharmony_ci				<< TestLog::EndMessage;
1552e5c31af7Sopenharmony_ci
1553e5c31af7Sopenharmony_ci			isOk = false;
1554e5c31af7Sopenharmony_ci		}
1555e5c31af7Sopenharmony_ci
1556e5c31af7Sopenharmony_ci		if (context != EGL_NO_CONTEXT)
1557e5c31af7Sopenharmony_ci			egl.destroyContext(m_eglDisplay, context);
1558e5c31af7Sopenharmony_ci
1559e5c31af7Sopenharmony_ci		if (isOk)
1560e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1561e5c31af7Sopenharmony_ci		else
1562e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1563e5c31af7Sopenharmony_ci
1564e5c31af7Sopenharmony_ci		return STOP;
1565e5c31af7Sopenharmony_ci	}
1566e5c31af7Sopenharmony_ci};
1567e5c31af7Sopenharmony_ci
1568e5c31af7Sopenharmony_ciclass InvalidContextCase : public RobustnessTestCase
1569e5c31af7Sopenharmony_ci{
1570e5c31af7Sopenharmony_cipublic:
1571e5c31af7Sopenharmony_ci	InvalidContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
1572e5c31af7Sopenharmony_ci		: RobustnessTestCase (eglTestCtx, name, description) {}
1573e5c31af7Sopenharmony_ci
1574e5c31af7Sopenharmony_ci	TestCase::IterateResult	iterate	(void)
1575e5c31af7Sopenharmony_ci	{
1576e5c31af7Sopenharmony_ci		const Library&	egl		= m_eglTestCtx.getLibrary();
1577e5c31af7Sopenharmony_ci		TestLog&		log		= m_testCtx.getLog();
1578e5c31af7Sopenharmony_ci		bool			isOk	= true;
1579e5c31af7Sopenharmony_ci
1580e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message
1581e5c31af7Sopenharmony_ci			<< "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"
1582e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
1583e5c31af7Sopenharmony_ci
1584e5c31af7Sopenharmony_ci		const EGLint attribList[] =
1585e5c31af7Sopenharmony_ci		{
1586e5c31af7Sopenharmony_ci			EGL_CONTEXT_CLIENT_VERSION, 3,
1587e5c31af7Sopenharmony_ci			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
1588e5c31af7Sopenharmony_ci			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
1589e5c31af7Sopenharmony_ci			EGL_NONE
1590e5c31af7Sopenharmony_ci		};
1591e5c31af7Sopenharmony_ci
1592e5c31af7Sopenharmony_ci		if (eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_create_context_robustness"))
1593e5c31af7Sopenharmony_ci		{
1594e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL_EXT_create_context_robustness to be unsupported");
1595e5c31af7Sopenharmony_ci			return STOP;
1596e5c31af7Sopenharmony_ci		}
1597e5c31af7Sopenharmony_ci
1598e5c31af7Sopenharmony_ci		logAttribList(m_eglTestCtx, attribList);
1599e5c31af7Sopenharmony_ci		EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
1600e5c31af7Sopenharmony_ci
1601e5c31af7Sopenharmony_ci		const EGLenum error = egl.getError();
1602e5c31af7Sopenharmony_ci		if (error != EGL_BAD_ATTRIBUTE)
1603e5c31af7Sopenharmony_ci		{
1604e5c31af7Sopenharmony_ci			log << TestLog::Message
1605e5c31af7Sopenharmony_ci				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
1606e5c31af7Sopenharmony_ci				<< TestLog::EndMessage;
1607e5c31af7Sopenharmony_ci
1608e5c31af7Sopenharmony_ci			isOk = false;
1609e5c31af7Sopenharmony_ci		}
1610e5c31af7Sopenharmony_ci
1611e5c31af7Sopenharmony_ci		if (context != EGL_NO_CONTEXT)
1612e5c31af7Sopenharmony_ci			egl.destroyContext(m_eglDisplay, context);
1613e5c31af7Sopenharmony_ci
1614e5c31af7Sopenharmony_ci		if (isOk)
1615e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1616e5c31af7Sopenharmony_ci		else
1617e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1618e5c31af7Sopenharmony_ci
1619e5c31af7Sopenharmony_ci		return STOP;
1620e5c31af7Sopenharmony_ci	}
1621e5c31af7Sopenharmony_ci};
1622e5c31af7Sopenharmony_ci
1623e5c31af7Sopenharmony_ci} // anonymous
1624e5c31af7Sopenharmony_ci
1625e5c31af7Sopenharmony_ci// Note: Tests limited to openGLES 3.1 contexts only
1626e5c31af7Sopenharmony_ciTestCaseGroup* createRobustnessTests (EglTestContext& eglTestCtx)
1627e5c31af7Sopenharmony_ci{
1628e5c31af7Sopenharmony_ci	de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "robustness", "KHR_robustness tests"));
1629e5c31af7Sopenharmony_ci
1630e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const contextCreationTestGroup			= new TestCaseGroup(eglTestCtx, "create_context",						"Test valid context_creation attributes");
1631e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const contextResetTestGroup				= new TestCaseGroup(eglTestCtx, "reset_context",						"Test context resets scenarios");
1632e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const negativeContextTestGroup			= new TestCaseGroup(eglTestCtx, "negative_context",						"Test invalid context creation attributes");
1633e5c31af7Sopenharmony_ci
1634e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const shadersTestGroup					= new TestCaseGroup(eglTestCtx, "shaders",								"Shader specific context reset tests");
1635e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const fixedFunctionTestGroup			= new TestCaseGroup(eglTestCtx, "fixed_function_pipeline",				"Fixed function pipeline context reset tests with robust context");
1636e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const fixedFunctionNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "fixed_function_pipeline_non_robust",	"Fixed function pipeline context reset tests with non-robust context");
1637e5c31af7Sopenharmony_ci
1638e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const outOfBoundsTestGroup				= new TestCaseGroup(eglTestCtx, "out_of_bounds",						"Out of bounds access scenarios with robust context");
1639e5c31af7Sopenharmony_ci
1640e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const outOfBoundsNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "out_of_bounds_non_robust",				"Out of bounds access scenarios with non-robust context");
1641e5c31af7Sopenharmony_ci
1642e5c31af7Sopenharmony_ci	const string resetScenarioDescription	= "query error states and reset notifications";
1643e5c31af7Sopenharmony_ci
1644e5c31af7Sopenharmony_ci	// out-of-bounds test cases
1645e5c31af7Sopenharmony_ci	{
1646e5c31af7Sopenharmony_ci		// robust context
1647e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const uboReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
1648e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const uboWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
1649e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const ssboWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1650e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const ssboReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1651e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const localWriteArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
1652e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const localReadArrayResetTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
1653e5c31af7Sopenharmony_ci
1654e5c31af7Sopenharmony_ci		// non-robust context (internal use only)
1655e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const uboReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
1656e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const uboWriteArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "uniform_block",		"Uniform Block Accesses");
1657e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const ssboWriteArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1658e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const ssboReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1659e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const localWriteArrayResetNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
1660e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const localReadArrayResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "local_array",			"Local array accesses");
1661e5c31af7Sopenharmony_ci
1662e5c31af7Sopenharmony_ci		static const RobustnessTestCase::Params s_outOfBoundReadCases[] =
1663e5c31af7Sopenharmony_ci		{
1664e5c31af7Sopenharmony_ci			// ubo read only
1665e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_READ),
1666e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_READ),
1667e5c31af7Sopenharmony_ci			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),
1668e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_UBO, READWRITETYPE_READ),
1669e5c31af7Sopenharmony_ci
1670e5c31af7Sopenharmony_ci			// ssbo read only
1671e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
1672e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
1673e5c31af7Sopenharmony_ci			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),
1674e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
1675e5c31af7Sopenharmony_ci
1676e5c31af7Sopenharmony_ci			// local array read only
1677e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1678e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1679e5c31af7Sopenharmony_ci			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),
1680e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1681e5c31af7Sopenharmony_ci
1682e5c31af7Sopenharmony_ci			// ubo read only (non-robust)
1683e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_READ),
1684e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_READ),
1685e5c31af7Sopenharmony_ci			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),
1686e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_UBO, READWRITETYPE_READ),
1687e5c31af7Sopenharmony_ci
1688e5c31af7Sopenharmony_ci			// ssbo read only (non-robust)
1689e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
1690e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_READ),
1691e5c31af7Sopenharmony_ci			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),
1692e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_SSBO, READWRITETYPE_READ),
1693e5c31af7Sopenharmony_ci
1694e5c31af7Sopenharmony_ci			// local array read only (non-robust)
1695e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1696e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1697e5c31af7Sopenharmony_ci			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),
1698e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1699e5c31af7Sopenharmony_ci		};
1700e5c31af7Sopenharmony_ci
1701e5c31af7Sopenharmony_ci		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundReadCases); ++testNdx)
1702e5c31af7Sopenharmony_ci		{
1703e5c31af7Sopenharmony_ci			const RobustnessTestCase::Params& test = s_outOfBoundReadCases[testNdx];
1704e5c31af7Sopenharmony_ci
1705e5c31af7Sopenharmony_ci			if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1706e5c31af7Sopenharmony_ci				uboReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1707e5c31af7Sopenharmony_ci
1708e5c31af7Sopenharmony_ci			if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1709e5c31af7Sopenharmony_ci				uboReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1710e5c31af7Sopenharmony_ci
1711e5c31af7Sopenharmony_ci			if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1712e5c31af7Sopenharmony_ci				ssboReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1713e5c31af7Sopenharmony_ci
1714e5c31af7Sopenharmony_ci			if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1715e5c31af7Sopenharmony_ci				ssboReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1716e5c31af7Sopenharmony_ci
1717e5c31af7Sopenharmony_ci			if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1718e5c31af7Sopenharmony_ci				localReadArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1719e5c31af7Sopenharmony_ci
1720e5c31af7Sopenharmony_ci			if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1721e5c31af7Sopenharmony_ci				localReadArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1722e5c31af7Sopenharmony_ci		}
1723e5c31af7Sopenharmony_ci
1724e5c31af7Sopenharmony_ci		static const RobustnessTestCase::Params s_outOfBoundWriteCases[] =
1725e5c31af7Sopenharmony_ci		{
1726e5c31af7Sopenharmony_ci			// ubo write only
1727e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1728e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1729e5c31af7Sopenharmony_ci			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),
1730e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1731e5c31af7Sopenharmony_ci
1732e5c31af7Sopenharmony_ci			// ssbo write only
1733e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1734e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1735e5c31af7Sopenharmony_ci			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),
1736e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1737e5c31af7Sopenharmony_ci
1738e5c31af7Sopenharmony_ci			// local array write only
1739e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1740e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1741e5c31af7Sopenharmony_ci			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),
1742e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1743e5c31af7Sopenharmony_ci
1744e5c31af7Sopenharmony_ci			// ubo write only (non-robust)
1745e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1746e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1747e5c31af7Sopenharmony_ci			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),
1748e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1749e5c31af7Sopenharmony_ci
1750e5c31af7Sopenharmony_ci			// ssbo write only (non-robust)
1751e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1752e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1753e5c31af7Sopenharmony_ci			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),
1754e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1755e5c31af7Sopenharmony_ci
1756e5c31af7Sopenharmony_ci			// local array write only (non-robust)
1757e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("vertex",				"Provoke a context reset in vertex shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1758e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("fragment",				"Provoke a context reset in fragment shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,			RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1759e5c31af7Sopenharmony_ci			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),
1760e5c31af7Sopenharmony_ci			RobustnessTestCase::Params ("compute",				"Provoke a context reset in compute shader and ",				ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,		RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1761e5c31af7Sopenharmony_ci		};
1762e5c31af7Sopenharmony_ci
1763e5c31af7Sopenharmony_ci		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundWriteCases); ++testNdx)
1764e5c31af7Sopenharmony_ci		{
1765e5c31af7Sopenharmony_ci			const RobustnessTestCase::Params& test = s_outOfBoundWriteCases[testNdx];
1766e5c31af7Sopenharmony_ci
1767e5c31af7Sopenharmony_ci				if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1768e5c31af7Sopenharmony_ci					uboWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1769e5c31af7Sopenharmony_ci
1770e5c31af7Sopenharmony_ci				if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1771e5c31af7Sopenharmony_ci					uboWriteArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1772e5c31af7Sopenharmony_ci
1773e5c31af7Sopenharmony_ci				if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1774e5c31af7Sopenharmony_ci					ssboWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1775e5c31af7Sopenharmony_ci
1776e5c31af7Sopenharmony_ci				if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1777e5c31af7Sopenharmony_ci					ssboWriteArrayResetNonRobustTestGroup->addChild		(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1778e5c31af7Sopenharmony_ci
1779e5c31af7Sopenharmony_ci				if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1780e5c31af7Sopenharmony_ci					localWriteArrayResetTestGroup->addChild				(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1781e5c31af7Sopenharmony_ci
1782e5c31af7Sopenharmony_ci				if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1783e5c31af7Sopenharmony_ci					localWriteArrayResetNonRobustTestGroup->addChild	(new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
1784e5c31af7Sopenharmony_ci		}
1785e5c31af7Sopenharmony_ci
1786e5c31af7Sopenharmony_ci		// robust Context
1787e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const outOfBoundsResetReadAccessTestGroup	= new TestCaseGroup(eglTestCtx, "reads",	"Out of bounds read accesses");
1788e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const outOfBoundsResetWriteAccessTestGroup	= new TestCaseGroup(eglTestCtx, "writes",	"Out of bounds write accesses");
1789e5c31af7Sopenharmony_ci
1790e5c31af7Sopenharmony_ci		outOfBoundsResetReadAccessTestGroup->addChild(uboReadArrayResetTestGroup);
1791e5c31af7Sopenharmony_ci		outOfBoundsResetReadAccessTestGroup->addChild(ssboReadArrayResetTestGroup);
1792e5c31af7Sopenharmony_ci		outOfBoundsResetReadAccessTestGroup->addChild(localReadArrayResetTestGroup);
1793e5c31af7Sopenharmony_ci
1794e5c31af7Sopenharmony_ci		outOfBoundsResetWriteAccessTestGroup->addChild(uboWriteArrayResetTestGroup);
1795e5c31af7Sopenharmony_ci		outOfBoundsResetWriteAccessTestGroup->addChild(ssboWriteArrayResetTestGroup);
1796e5c31af7Sopenharmony_ci		outOfBoundsResetWriteAccessTestGroup->addChild(localWriteArrayResetTestGroup);
1797e5c31af7Sopenharmony_ci
1798e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const outOfBoundsResetTestGroup		= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
1799e5c31af7Sopenharmony_ci
1800e5c31af7Sopenharmony_ci		outOfBoundsResetTestGroup->addChild(outOfBoundsResetReadAccessTestGroup);
1801e5c31af7Sopenharmony_ci		outOfBoundsResetTestGroup->addChild(outOfBoundsResetWriteAccessTestGroup);
1802e5c31af7Sopenharmony_ci
1803e5c31af7Sopenharmony_ci		outOfBoundsTestGroup->addChild(outOfBoundsResetTestGroup);
1804e5c31af7Sopenharmony_ci
1805e5c31af7Sopenharmony_ci		// non-robust Context (internal use only)
1806e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const outOfBoundsResetReadAccessNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "reads",	"Out of bounds read accesses");
1807e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const outOfBoundsResetWriteAccessNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "writes",	"Out of bounds write accesses");
1808e5c31af7Sopenharmony_ci
1809e5c31af7Sopenharmony_ci		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(uboReadArrayResetNonRobustTestGroup);
1810e5c31af7Sopenharmony_ci		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(ssboReadArrayResetNonRobustTestGroup);
1811e5c31af7Sopenharmony_ci		outOfBoundsResetReadAccessNonRobustTestGroup->addChild(localReadArrayResetNonRobustTestGroup);
1812e5c31af7Sopenharmony_ci
1813e5c31af7Sopenharmony_ci		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(uboWriteArrayResetNonRobustTestGroup);
1814e5c31af7Sopenharmony_ci		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(ssboWriteArrayResetNonRobustTestGroup);
1815e5c31af7Sopenharmony_ci		outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(localWriteArrayResetNonRobustTestGroup);
1816e5c31af7Sopenharmony_ci
1817e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const outOfBoundsResetNonRobustTestGroup		= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
1818e5c31af7Sopenharmony_ci
1819e5c31af7Sopenharmony_ci		outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetReadAccessNonRobustTestGroup);
1820e5c31af7Sopenharmony_ci		outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetWriteAccessNonRobustTestGroup);
1821e5c31af7Sopenharmony_ci
1822e5c31af7Sopenharmony_ci		outOfBoundsNonRobustTestGroup->addChild(outOfBoundsResetNonRobustTestGroup);
1823e5c31af7Sopenharmony_ci	}
1824e5c31af7Sopenharmony_ci
1825e5c31af7Sopenharmony_ci	// fixed function test cases
1826e5c31af7Sopenharmony_ci	{
1827e5c31af7Sopenharmony_ci		// robust context
1828e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const fixedFunctionResetStatusTestGroup				= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
1829e5c31af7Sopenharmony_ci
1830e5c31af7Sopenharmony_ci		// non-robust context (internal use only)
1831e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const fixedFunctionResetStatusNonRobustTestGroup	= new TestCaseGroup(eglTestCtx, "reset_status",	"Tests that query the reset status after a context reset has occurred");
1832e5c31af7Sopenharmony_ci
1833e5c31af7Sopenharmony_ci		static const RobustnessTestCase::Params s_fixedFunctionPipelineCases[] =
1834e5c31af7Sopenharmony_ci		{
1835e5c31af7Sopenharmony_ci			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),
1836e5c31af7Sopenharmony_ci			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),
1837e5c31af7Sopenharmony_ci
1838e5c31af7Sopenharmony_ci			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),
1839e5c31af7Sopenharmony_ci			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),
1840e5c31af7Sopenharmony_ci		};
1841e5c31af7Sopenharmony_ci
1842e5c31af7Sopenharmony_ci		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_fixedFunctionPipelineCases); ++testNdx)
1843e5c31af7Sopenharmony_ci		{
1844e5c31af7Sopenharmony_ci			const RobustnessTestCase::Params& test = s_fixedFunctionPipelineCases[testNdx];
1845e5c31af7Sopenharmony_ci			if (test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1846e5c31af7Sopenharmony_ci				fixedFunctionResetStatusTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
1847e5c31af7Sopenharmony_ci			else
1848e5c31af7Sopenharmony_ci				fixedFunctionResetStatusNonRobustTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
1849e5c31af7Sopenharmony_ci		}
1850e5c31af7Sopenharmony_ci
1851e5c31af7Sopenharmony_ci		fixedFunctionTestGroup->addChild(fixedFunctionResetStatusTestGroup);
1852e5c31af7Sopenharmony_ci		fixedFunctionNonRobustTestGroup->addChild(fixedFunctionResetStatusNonRobustTestGroup);
1853e5c31af7Sopenharmony_ci	}
1854e5c31af7Sopenharmony_ci
1855e5c31af7Sopenharmony_ci	// context creation query cases
1856e5c31af7Sopenharmony_ci	{
1857e5c31af7Sopenharmony_ci		contextCreationTestGroup->addChild(new QueryRobustAccessCase	(eglTestCtx, "query_robust_access",		"Query robust access after successfully creating a robust context"));
1858e5c31af7Sopenharmony_ci		contextCreationTestGroup->addChild(new NoResetNotificationCase	(eglTestCtx, "no_reset_notification",	"Query reset notification strategy after specifying GL_NO_RESET_NOTIFICATION"));
1859e5c31af7Sopenharmony_ci		contextCreationTestGroup->addChild(new LoseContextOnResetCase	(eglTestCtx, "lose_context_on_reset",	"Query reset notification strategy after specifying GL_LOSE_CONTEXT_ON_RESET"));
1860e5c31af7Sopenharmony_ci	}
1861e5c31af7Sopenharmony_ci
1862e5c31af7Sopenharmony_ci	// invalid context creation cases
1863e5c31af7Sopenharmony_ci	{
1864e5c31af7Sopenharmony_ci		negativeContextTestGroup->addChild(new InvalidContextCase			(eglTestCtx, "invalid_robust_context_creation",			"Create a non-robust context but specify a reset notification strategy"));
1865e5c31af7Sopenharmony_ci		negativeContextTestGroup->addChild(new InvalidShareContextCase		(eglTestCtx, "invalid_robust_shared_context_creation",	"Create a context share group with conflicting reset notification strategies"));
1866e5c31af7Sopenharmony_ci		negativeContextTestGroup->addChild(new InvalidNotificationEnumCase	(eglTestCtx, "invalid_notification_strategy_enum",		"Create a robust context using EGL 1.5 only enum with EGL versions <= 1.4" ));
1867e5c31af7Sopenharmony_ci	}
1868e5c31af7Sopenharmony_ci
1869e5c31af7Sopenharmony_ci	shadersTestGroup->addChild(outOfBoundsTestGroup);
1870e5c31af7Sopenharmony_ci	shadersTestGroup->addChild(outOfBoundsNonRobustTestGroup);
1871e5c31af7Sopenharmony_ci
1872e5c31af7Sopenharmony_ci	contextResetTestGroup->addChild(shadersTestGroup);
1873e5c31af7Sopenharmony_ci	contextResetTestGroup->addChild(fixedFunctionTestGroup);
1874e5c31af7Sopenharmony_ci	contextResetTestGroup->addChild(fixedFunctionNonRobustTestGroup);
1875e5c31af7Sopenharmony_ci
1876e5c31af7Sopenharmony_ci	group->addChild(contextCreationTestGroup);
1877e5c31af7Sopenharmony_ci	group->addChild(contextResetTestGroup);
1878e5c31af7Sopenharmony_ci	group->addChild(negativeContextTestGroup);
1879e5c31af7Sopenharmony_ci
1880e5c31af7Sopenharmony_ci	return group.release();
1881e5c31af7Sopenharmony_ci}
1882e5c31af7Sopenharmony_ci
1883e5c31af7Sopenharmony_ci} // egl
1884e5c31af7Sopenharmony_ci} // deqp
1885